Maven does not pick up war dependency in pom.xml - java

I have a multi module Maven project. Parent project and then two other modules, one of which builds the war through its pom.xml.
Parent Project
---- Java Project
---- War Project
I build the war from parent project. There is another external war dependency in War project's pom.xml. Jars in that project are needed to build a specific profile, which is specified in War project's pom.xml. Maven cannot get those jars from war dependency. I ran the following command
mvn install:install <information about war>
to put it in local.m2 repository, but Maven doesn't pick anything from that dependency. I understand that Maven processes war dependencies differently than it does a jar dependency but I am unable to understand as to how will it pick it up? Any help will be appreciated. Thanks.
Edit
This is how I try to include the war dependency
<dependency>
<groupId>com.example</groupId>
<artifactId>my-id-artifact</artifactId>
<version>1.0.0</version>
<type>war</type>
</dependency>
Also, I would like to mention that I use that maven war dependency in <overlay> tag.

Related

Project as dependency not packaged in .war file

I have a Jersey Tomcat project B that depends on another similar project A, I am developing on Eclipse.
When I run A on it's own, it runs with no problems. The export configuration for its build path is:
And the deployment assembly for A is:
Then, for project B, I imported project A into the java build path like this:
The build path for project B looks like this:
And the web deployment assembly for project B is:
Project A is listed as a .war, I am not sure if this is related to the issue. The pom.xml for project A lists war as packaging:
<packaging>war</packaging>
The pom.xml for project B mentions project A like so:
<dependency>
<groupId>some.project.A</groupId>
<artifactId>flocktracker</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
Eclipse doesn't show any issues until when I try to deploy in a Tomcat server, whe I get this error:
java.lang.NoClassDefFoundError: some/project/A/SomeClassInA
at some.project.B.SomeClassInB.<init>(SomeClassInB.java:##)
If it helps, SomeClassInA is an implementation of org.glassfish.jersey.server.ResourceConfig.
SomeClassInA is mentioned in the web.xml file like so:
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>some.projectA.SomeClassInA</param-value>
</init-param>
SomeClassInA is an implementation of javax.ws.rs.ext.ContextResolver<T>
I used right click on project > export > WAR file to examine the contents of the file and I couldn't find the classes of Project A on WEB-INF/classess or elsewhere in the .war file.
Is there something I am missing or that I am doing wrong?
Thanks!
Keeping the Eclipse tooling aside, from a Maven configuration perspective:
Maven does not load classes from a WAR artifact, as it would load from a JAR artifact.
Ideally WAR artifacts are not supposed to be used as a dependency, unless you're building a final EAR artifact.
You have the following choices. All of them require a modification to ProjectB as well:
Although this is the least likely case, if ProjectA is not used for deploying a web application, you could just change its packaging to jar
You could move all the required classes to a separate module that builds a JAR, and use this dependency in both ProjectA and ProjectB.
If you do not want to move the classes to another module/project, you can configure the war plugin in ProjectA to generate a jar artifact alongside the war artifact, using <attachClasses>true</attachClasses>
<project>
...
<artifactId>yourWebapp</artifactId>
<version>yourVersion</version>
...
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
This produces a classes artifact in ProjectA, which can be used in ProjectB as a dependency with <classifier>classes</classifier>
<dependency>
<groupId>yourGroupId</groupId>
<artifactId>yourWebapp</artifactId>
<version>yourVersion</version>
<classifier>classes</classifier>
</dependency>

Plugin dependency on an internal module

I have many modules in my project and let's say two of them are module A and module B. I have specified a dependency on the JAR of module A under the plugin tag of the pom for module B.
POM for module B:
<plugin>
............
............
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>module-A</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
The issue I am facing is that before the build begins i.e. before the JAR for module A is created, pom for module B is getting scanned and I am getting error that says:
"The POM for module A is missing, no dependency information available"
I do not have access to an online repository where I can host JAR for module A. How can I go about doing this locally? How do I ensure that JAR for module A is present locally before this scan takes place?
Usually, Maven determines the correct build order automatically.
I do not know whether plugin dependencies are accounted for as well.
In case of doubt I would move module-A before module-B in the list of modules in the main POM.

Maven: classes folder generated in multi-module maven project is empty

i have 3 modules in my maven project , each of the modules generate a jar file.
And then i have a 4th module that generates war out of these jars
Here is my POM which is parent of all modules
<modules>
<module>A</module>
<module>B</module>
<module>C</module>
<module>DWAR</module>
</modules>
IN DWAR's pom , I have specified dependencies on all the three modules A,B,C
<dependency>
<groupId>yyyy</groupId>
<artifactId>A</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
.
. And So on.
My war builds successfully, the lib folder of war contains all the jars, but classes folder is empty.
But in each of the modules A,B,C classes folder is populated with compiled classes.
What am I missing?
What you describe is the expected behaviour: Your war contains the three jars. The war itself has no java source files, so its classes folder is empty.
Building a war does not unpack the included jars, but adds them into the war as a whole.

Maven assembly JAR in EAR

For reasons that I won't go into, I need to build the following structure:
EAR
|
|-- Uber-JAR
|
|-- WAR
I can build the uber JAR with the Maven Assembly plugin, but when I try to include it in the EAR (built with the Maven EAR plugin) it includes a normal JAR version, which has no sources (because I'm using the uber JAR to pull all the sources in the project together).
How can I get the uber JAR included in the EAR?
This is one way to fix it. If there's a better way I'd like to know it :)
Just include:
<earSourceDirectory>${basedir}</earSourceDirectory>
<earSourceIncludes>/path/to/jar.jar</earSourceIncludes>
in the EAR plugin configuration.
EDIT: Seems I spoke too soon. In the project's parent pom I have all the modules listed to build, with the uber JAR above the EAR module (as the last two modules).
It won't build the whole project:
'Artifact <ARTIFACT> (included by module) does not have an artifact with a file'
EDIT (again):
Final Answer
So, finally, in the configuration for the Maven Assembly plugin, I have:
<configuration>
...
<finalName>myjarname</finalName>
</configuration>
This creates a JAR file called simply 'myjarname.jar'.
In the Maven EAR plugin configuration, I use the following structure:
<configuration>
...
<modules>
...
<ejbModule>
<groupId>com.mygroup</groupId>
<artifactId>myartifact</artifactId>
<bundleFileName>myjarname.jar</bundleFileName>
</ejbModule>
</modules>
</configuration>
This grabs the specific jar and puts it in the EAR. Voila!

Manually installed maven dependencies not visible in Eclipse import

I have installed maven dependency using the command below
mvn install:install-file -Dfile=d2_lib.war -DgroupId=com.emc.d2fs -DartifactId=d2_lib -Dversion=1.0 -Dpackaging=war -DlocalRepositoryPath="C:\Users\kumarr23\.m2\repository"
I have added this dependency in my root pom.xml as below
<dependency>
<groupId>com.emc.d2fs</groupId>
<artifactId>d2_lib</artifactId>
<version>1.0</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
I can see when I do maven install the jars inside my final war,
when i try importing these classes from eclipse these classes are not included, Is there some thing I am missing?
I am new to maven and i am stuck here !
please advise
Please check if you have d2_lib.war file at the location from where you are running command or else mention the full path of d2_lib.war in command and try again , i believe with the command you specify it is not copying the war file since war file path is not defined properly , you can confirm this by checking if war file is copied to your local maven repository
mvn install:install-file -Dfile=d2_lib.war -DgroupId=com.emc.d2fs -DartifactId=d2_lib -Dversion=1.0 -Dpackaging=war -DlocalRepositoryPath="C:\Users\kumarr23.m2\repository"
There is a convention in maven that java code lives in a .jar file and web classes live in a .war file. When you include a dependency with the war type in your web project, maven will treat the included file as an overlay. This basically means that maven will package the contents of the dependency into your war file, however it will not include the libraries in that war as java code the way you are looking for.
When a war file is created, if the creator also wants people to get at the java code and transitive dependencies the code is based off of, they can use the maven-war-plugin to set a configuration tag of <attachClasses>true</attachClasses>. This will generate an additional artifact in the form of artifactId-version-classes.jar, along with the normal artifactId-version.war file.
When you include both the war as an overlay and the classes jar as a normal dependency, you will be able to see in your dependency tree that maven is only pulling in transitive dependencies from the jar file dependency, not the war.
In your case, you need to find the classes jar file and install it along with the war file in your local maven repository. Then you can add the classes jar to your pom.xml like so:
old pom.xml
<dependency>
<groupId>com.emc.d2fs</groupId>
<artifactId>d2_lib</artifactId>
<version>1.0</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
new pom.xml
<dependency>
<groupId>com.emc.d2fs</groupId>
<artifactId>d2_lib</artifactId>
<version>1.0</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.emc.d2fs</groupId>
<artifactId>d2_lib</artifactId>
<version>1.0</version>
<classifier>classes</classifier>
</dependency>

Categories