how to expose WEB-INF/lib inside war using maven - 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

Related

Make a jar that has a classifier by default

We have a project called core-services. This builds three jars:
core-services-client Contains all client classes
core-services-server: Contains all server and client classes
core-services-test: Contains all junit classes
Right now, I build the core-services-server jar by default, and then use assemblies to build the client and test jars. If a developer wants to use the client or test jars, they must specify a classifier. However, when they want to depend upon the server jar, they don't specify a classifier.
This will lead to developers just using the server jar when they really should be using the client jar. I'd like to build all three jars to require a classifier when using them as a dependency. However, I can't do this when specifying the project:
<groupId>com.vegicorp</groupId>
<artifactId>core-services</artifactId>
<version>1.0.0</version>
<classifier>server</classifier>
<packaging>jar</packaging>
I know I can use <finalName> to call the default jar core-services-server, but I want to make sure that if a developer depends upon the core-services, they must say whether they want the server, the client, or the testing classes. If I merely rename it, they will get the server jar by default.
How can I specify that the default jar has a classifier of server?
I figured it out. I can put the default classifier into the maven-jar-plugin configuration in my pom.xml:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<!-- All other configuration information is in the parent pom -->
<configuration>
<classifier>server</classifier>
</configuration>
</plugin>
When I do mvn deploy, I get a warning that No primary artifact to deploy, deploying attached artifacts instead, and all three jars deploy with classifiers.

How to auto-deploy EJB jar with TomEE maven plugin

I have a stateless EJB SOAP Web Service that is packaged in jar file.
Is it possible to setup auto-deploy with Tomee maven plugin when the app consists of only one EJB jar file?
For example, this site indicates that a web context defined in server.xml is required. My synch setup is same as the site suggests.
mvn compile
command does nothing but compile the sources as it normally does.
Is there a possibility to setup something like this with EJB jar or is a WAR package needed in any case?
Thanks.
UPDATE
In order to get the TomEE Maven plugin to work at all with jar files, I added the following in pom.xml configuration section
<apps>
<app>my.group:my-ejb-app:1.0:jar</app>
</apps>
We use the maven tomcat7 plugin to do exactly this. Here's the trick, because Apache TomEE is JEE6, you can deploy EJBs in wars.
So there are two ways to do what you want... One, skip the Jar packaging for your application and make your EJBs be WARs. If this doesn't sound appealing, the other way is to create a separate project that's a WAR, but pulls in your EJB jar as a dependency.
In either case, then you can then use the tomcat7 plugin to deploy your projects easily to Apache TomEE like this mvn tomcat7:deploy provided you fill out the server section of your pom correctly. Example:
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<server>crabs</server>
<url>http://crabs/manager/text</url>
<path>/${project.artifactId}</path>
<update>true</update>
</configuration>
</plugin>
</plugins>
</build>
Make sure you have a user in tomcat-users.xml on the server that has the proper deployment permissions to manager-text. Also, put the server configuration into your ~/.m2/settings.xml:
...
<servers>
<server>
<id>crabs</id>
<username>deploy</username>
<password>your password</password>
</server>
...

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 deploy Maven dependencies automatically into JBoss as OSGI bundles?

I have a project that deploys an standalone OSGí Apache ServiceMix application. It has tons of dependencies and it is built with Maven. Now I want to deploy this application into a JBoss AS. I found an interesting Maven plugin called jboss-as-maven-plugin (org.jboss.as.plugins) to deploy anything. I use maven-bundle-plugin (org.apache.felix) to construct my bundles and it works fine, but when I deploy the project bundles, the deployment fails because dependencies are not satisfied.
How can I automatically bundle and deploy all the dependency tree with a Maven goal? Is it possible? My project has dozens of dependencies declared on the pom.xml and some of them are other projects in my workspace.
Currently the only solution to this I know are the Karaf features. You can create a feature file out of your pom dependencies.
I found that jboss seems to support subsystems. That may help to specify the bundles required to run your application. It does not seem to be the OSGi subsystem spec but for jboss this may already help. For OSGi spec 5 there is the standardized subsystem spec which may provide a standard way to do this across containers.
If jboss supports OBR (OSGi bundle repository) then you can limit the number of dependencies you have to specify.
If your application do not use OSGi per see, you may consider packing your application as a WAR which is deployable in JBoss.
Then you would need to use web.xml to bootstrap your application, such as using a Spring XML file.
There is a Camel example as a WAR here: http://camel.apache.org/servlet-tomcat-example.html
You can autoinstall your bundles with org.apache.sling plugin
<plugin>
<groupId>org.apache.sling</groupId>
<artifactId>maven-sling-plugin</artifactId>
<executions>
<execution>
<id>install-bundle</id>
<goals>
<goal>install</goal>
</goals>
</execution>
</executions>
<configuration>
<slingUrl>http://localhost:8181/system/console/install</slingUrl>
<user>karaf</user>
<password>karaf</password>
</configuration>
</plugin>
you can find detailed pom.xml from Adobe website :https://docs.adobe.com/docs/en/cq/5-6-1/developing/developmenttools/how-to-build-aem-projects-using-apache-maven.html
or http://www.cqblueprints.com/tipsandtricks/build-and-deploy-osgi/build-deploy-osgi-1.html

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

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>

Resources