How to refer shared library in EAR containing EJB jar in it built using maven as separate artifacts - maven

I am using maven to build applications.
I have deployed a WAR file containing many common jars as shared library in application server.
I have an artifact (say A-EJB) of packaging type EJB. I have built the ejb jar file.
I have an another artifact (say A-EAR) of packaging type EAR.
I have added A-EJB dependency in pom file of A-EAR. I could build the EAR file and for adding shared library reference, I have added library reference in weblogic-application.xml of EAR.
In my final EAR file, I could see A-EJB.jar file, other dependency jar files of A-EAR artifact.
EAR structure:
--------------APP-INF\lib\some jars
--------------META-INF\application.xml, MANIFEST.MF, weblogic-application.xml
--------------A-ejb.jar
The class files of A-EJB.jar requires reference of common jars in shared library.
Ideally, I am expecting the deployment should happen successfully but this is not happening. Even though I have shared library reference in EAR file, the deployment fails due to classNotFoundException while preparing the EJB module during deployment.
The class files of A-EJB.jar searches for required jar files for reference but they are available in shared library and shared library is not used even EAR file has the reference to it.
Exception:
weblogic.application.ModuleException: Exception preparing module: EJBModule
[EJB:011023]An error occurred while reading the deployment descriptor. The error was:
...........................................................
Caused By: java.lang.ClassNotFoundException:
............................................................
So, this means even though EAR had a shared library reference, the ejb.jar present inside the EAR did not have reference to shared library. Is this true ?
Has anyone faced this exception and scenario. Kindly help me about resolving this issue.

I suggest you to use the ear plugin with this settings.. might help..
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<configuration>
<modules>
<ejbModule>
<groupId>ur ejb</groupId>
<artifactId>ur ejb Id</artifactId>
</ejbModule>
<jarModule>
<groupId>......</groupId>
<artifactId>......</artifactId>
</jarModule>
....
....
Other jar modules to be included other than the one included in dependency tag
....
....
</modules>
<archive>
<manifest>
<addClasspath>false</addClasspath>
</manifest>
</archive>
<displayName>...name...</displayName>
<description>........desc.......</description>
</configuration>
</plugin>

Related

Package a multiple-entry jar using maven for hadoop project

I'm new to maven. I want to package a jar of my hadoop project with its dependencies, and then use it like:
hadoop jar project.jar com.abc.def.SomeClass1 -params ...
hadoop jar project.jar com.abc.def.AnotherClass -params ...
And I want to have multiple entry points for this jar (different hadoop jobs).
How could I do it?
Thanks!
There's two ways to create a jar with dependencies:
Hadoop supports jars in a jar format - meaning that your jar contain contain a lib folder of jars that will be added to the classpath at job submission and map / reduce task execution
You can unpack the jar dependencies and re-pack them with your classes into a single monolithic jar.
The first will require you to create a maven assembly definition file but in reality is more hassle than it's worth. The second also uses maven assemblies but utilizes a built in descriptor. To use the second, just add the following to your project -> build -> plugins section in the pom:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
Now when you run mvn package you'll get two jars in your target folder:
${project.name}-${project.version}.jar - Which will just contain classes and resources for your project
${project.name}-${project.version}-jar-with-dependencies.jar - which will contain your classes / resources and everything from your dependency tree with a scope of compile unpacked and repacked into a single jar
For multi entry points, you don't need to do anything specific, just make sure you don't define a Main-Class entry in the jar manifest (if you explicitly configure a manifest, otherwise the default doesn't name a Main-Class so you should be good)

How to include binary ejb-jar(no source project) file into ear file using maven?

I have an ejb-jar that is delivered by another team as a binary jar i.e. the ejb-jar contains only ejb class files(no source code). I need to include that ejb-jar as a ejb module to my ear file. My ear file has many other ejb/war modules. What is the best way to configure this thirdparty ejb-jar module into the ear using maven?
Thanks,
PB
Hi i would simply say:
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>2.8</version>
<configuration>
<modules>
<ejbModule>
<...>
</ejbModule>
</modules>
</configuration>
</plugin>
and don't forget to define the ejb-jar as a usual dependency to the ear project...
To test locally, use mvn install:install-file -Dfile=your.artifact.jar -DgroupId=your.org -DartifactId=your-artifact.jar -Dversion=1.0 -Dpackaging=ejb -DgeneratePom=true.
Once it is in your repository, you can use it just like any ejb dependency (as indicated by #khmarbaise).
If you are using Nexus or another artifact repository, then deploy there instead.

how to expose WEB-INF/lib inside war using maven

We are using an 3rd party war in our web app (war). In order to communicate with the war, we have created a bridge module (jar). The intention is to prevent our web app from directly communicating with the external war, but instead communicate through the bridge module.
All the 3 modules (2 wars and 1 jar) are inside an ear file which is deployed in JBoss.
ear
- war1 (our web app)
- war2 (external web app)
- bridge jar
Point to note is, the bridge jar uses some API (exposed as jars), which are present inside the WEB-INF/lib directory of the external war.
At the time of bringing up JBoss, we get java.lang.NoClassDefFoundError errors because the bridge jar is not able to find the API present in external war's WEB-INF/lib.
We do not want to place all external jars directly under ear as it will mean the external jars are not confined only within its war.
Is there a way to access the jars present inside WEB-INF/lib of the external war from the bridge jar? Can we achieve this using maven build process, or is there a better approach to this?
We've had a similar problem recently with our jars not able to see other jars. Resolved it by creating a manifest.mf using the maven-ejb-plugin defined in the pom.xml of the "bridge jar"
2 ways to do this:
a) if bridge jar's pom.xml already has war1 and war2 defined as dependencies - then use maven-ejb-plugin with
<configuration>
<ejbVersion>3.0</ejbVersion>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
This should autogenerate manifest.mf with a Classpath matching all dependencies defined in the pom
b) else, define your own manifest.mf with the right entries you need and point to it like so
<configuration>
<ejbVersion>3.0</ejbVersion>
<archive>
<manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
Since your jars are in the WEB-INF/lib of the war1, I think you should go for option 2 with a Manifest containing direct entries such as
Class-Path: WEB-INF/lib/some-external.jar

Maven-webstart-plugin to include runtime dependencies

When building a jnlp with the maven-webstart-plugin, I found that the runtime dependencies weren't being included in the jnlp.
I'm using a template like this:
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="$jnlpspec" codebase="${url}/${appName}" href="${outputFile}">
<information>
<title>${appName}</title>
<vendor>$project.Organization.Name</vendor>
<homepage href="${url}/${appName}"/>
<offline-allowed/>
</information>
<security>
<all-permissions/>
</security>
<resources>
<j2se version="$j2seVersion"/>
$dependencies
</resources>
<application-desc main-class="${main}" />
</jnlp>
How can I include the runtime dependencies? Well, I can include them all individually:
<plugin>
<groupId>org.codehaus.mojo.webstart</groupId>
<artifactId>webstart-maven-plugin</artifactId>
<configuration>
<dependencies>
<includes>
<include>groupId:artifactId</include>
...
</includes>
</dependencies>
...
</configuration>
</plugin>
...but ideally, I don't want to have to remember to change this every time I add a runtime dependency to my project.
Is there a way to instruct the plugin to include all runtime dependencies?
So it turns out that the default is to include all compile and runtime dependencies.
What was going on?
Well, I'm also using ant to deploy the jnlp onto a server, and in the ant file, $dependencies was being set using mvn:dependencies without the scope being specified as runtime. So adding the scope changes the $dependencies fileset which is incorporated into the jnlp file.
I use a parent pom configuration where one of the modules is the web start project. I like to keep this as minimal as possible. I have compile dependencies only to a logging library, the main application module (another module in the same parent pom structure), and jar files including native binaries. In addition to these compile dependencies, I have some test dependencies and a system dependency to a local javaws.jar file.
It seems that the maven webstart plugin includes any runtime dependencies from modules which is included to the web start project as a compile dependency.
It might be a solution for you to split up your project in a similar manner.
Regarding the native binaries. I had to modify the velocity template somewhat to get these dependencies as nativelib instead of jar resources.

Maven: Use assembly as resulting artefact - appendAssemblyId == false?

I have a multimodule project.
Last module is "assemble", which is intended to put few modules' .jar's together in a single big .jar, which I could use for distribution.
This module does nothing else, so I did this:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
...
</configuration>
</plugin>
</plugins>
I want this behavior to be able to simply run the resulting jar from IDE (NetBeans 7.0).
Maven does exactly what I want, but says this:
[assembly:single]
Reading assembly descriptor: src/assembly/assembly.xml
Building jar: /mnt/ssd1/_projekty/JBoss/bots/JawaBot/2.0/assemble/target/JawaBot-assemble-2.0.0-SNAPSHOT.jar
Configuration options: 'appendAssemblyId' is set to false, and 'classifier' is missing.
Instead of attaching the assembly file: /mnt/ssd1/_projekty/JBoss/bots/JawaBot/2.0/assemble/target/JawaBot-assemble-2.0.0-SNAPSHOT.jar, it will become the file for main project artifact.
NOTE: If multiple descriptors or descriptor-formats are provided for this project, the value of this file will be non-deterministic!
Replacing pre-existing project main-artifact file: /mnt/ssd1/_projekty/JBoss/bots/JawaBot/2.0/assemble/target/JawaBot-assemble-2.0.0-SNAPSHOT.jar
with assembly file: /mnt/ssd1/_projekty/JBoss/bots/JawaBot/2.0/assemble/target/JawaBot-assemble-2.0.0-SNAPSHOT.jar
This message seems like it's not a recommended way to achieve my goal.
Is there any better?
The assembly plugin will create an artifact with a 'classifier' consisting of the assembly ID from the descriptor. It won't create a main artifact AFAICT.
You might be happier with the maven-shade-plugin, plus configuring the maven-jar-plugin to set the manifest class name so that java -jar works. The shade plugin can produce a main artifact.

Resources