We have two different web application and we want to extend few controllers of one war into another war.
We are using maven to build the project.
to include war we have given its dependency as
<dependency>
<groupId>com.abc.exchange</groupId>
<artifactId>employer</artifactId>
<version>2.3.M2-SNAPSHOT</version>
<type>war</type>
<scope>compile</scope>
</dependency>
It is unable to build giving class not found exception.
Can any body help me out how to achieve this?
I am getting error maven build failed :
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project agent-war: Compilation failure: Compilation failure:
[ERROR] \projects\trunk_new\agent\src\main\java\com\platform\agent\web\AgentEmployeeController.java:[22,41] cannot find symbol
[ERROR] symbol : class EmployeeController
[ERROR] location: package com..platform.employer.web
You can define the war plugin to produce a separate jar file which is available via a classifier based on the configuration:
<configuration>
..
<attachClasses>true</attachClasses>
<archiveClasses>true</archiveClasses>
</configuration>
After that you can use this as a separate dependency in other projects. But the best to make a separate jar module out of it.
What you are doing is using a WAR file overlay. Maven does support this. However...
The WAR plugin executes in the package
phase. Any plugin, such as the Java compiler (which runs in the compile phase), that executes before this phase will not see any files that the WAR plugin has extracted. (here is the reference list of all Maven phases if that helps)
If you have the ability to refactor your project structure, the best way is to create a normal JAR project with your controllers and have both WARs pull this JAR in as a dependency.
If there is some reason why you can't do this, you will need to do something like:
Configure the WAR plugin to run in a phase earlier than compile
, such as generate-resources
and makes sure it extracts the overlay class files to ${project.build.outputDirectory}
.
You could also use the Maven Dependency Plugin's unpack goal to extract classes from the dependency WAR to ${project.build.outputDirectory}
.
But I do recommend if at all possible to refactor your controllers into a separate JAR, it is much easier and more maintainable.
put the controllers into a new jar project and make dependencies from your webprojects to this controllers.
Add the following plugins to your share maven war module (for creating war and jar artifact at the same time):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>make-a-jar</id>
<phase>compile</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<packaging>jar</packaging>
<artifactId>${project.artifactId}</artifactId>
<groupId>${project.groupId}</groupId>
<version>${project.version}</version>
<file>
${project.build.directory}/${project.artifactId}-${project.version}.jar
</file>
</configuration>
</execution>
</executions>
</plugin>
then add dependency to your dependent maven war module.
Java EE visability standards state that classes from one war shouldn't be available to classes in another war, when they're packaged as an EAR. Most containers will enforce this strictly.
You should put the code you wish to share into a JAR and include that as a dependency in the war you want to use.
In the war project pom.xml include
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
This will create your-project-0.0.1-SNAPSHOT-clases.jar in the target folder along with the war.
In the dependent project pom.xml include
<dependency>
<groupId>com.yourproject</groupId>
<artifactId>you-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<classifier>classes</classifier>
</dependency>
This worked for me. Hope it helps.
Edit: If we want only some class files into the jar then add this to pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>make-a-jar</id>
<phase>compile</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>classifier_name</classifier>
<includes>
<include>com/../..</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
In the dependent project pom.xml include
<dependency>
<groupId>com.yourproject</groupId>
<artifactId>you-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<classifier>classifier_name</classifier>
</dependency>
note: the classifier name must be same in both pom.xml files