I want to migrate about 15 Ant projects to Maven.
Current build with Ant:
project-1
project-2 (needs project-3 as dependency)
project-3
project-webresources (contains web resources needed by ALL other projects)
project-WAR (empty target project)
(project-1, project-2, project-3 contain additional web resources)
Now, different WARs have to be built:
For Deployment 1 (contains project-1 and project-webresources):
Java sources from project-1 are compiled and copied to project-WAR/WEB-INF/classes
Web resources from project-webresources and project-1 are copied to project-WAR/
For Deployment 2 (contains project-1, project-2, project-3 and project-webresources):
Java sources from project-1, project-2, project-3 are compiled an copied to project-WAR/WEB-INF/classes
Web resources from project-webresources, project-1, project-2 and project-3 are copied to project-WAR/
My plan to realize it with Maven:
The projects become modules and for every deployment I create a project which holds the needed modules and one target WAR artifact. For the project-webresources I use maven overlays.
Build-deployment-1:
(mvn install here to build the deployment-1 Web archive)
<packaging>pom</packaging>
<modules>
<module>project-1</module>
<module>project-webresources</module>
<module>WAR-deployment-1</module>
</modules>
WAR-deployment-1:
<packaging>jar</packaging>
<dependency>
<groupId>com.groupId</groupId>
<artifactId>project-webresources</artifactId>
<version>1.0-SNAPSHOT</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.groupId</groupId>
<artifactId>artifact-1</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
For the second WAR there will be projects like Build-deployment-2 and WAR-deployment-2 and so on which use other module combinations.
My problem:
What is the best way to copy all web resources from project-1 to WAR-deployment-1? If I use maven-resources-plugin in project-1 to copy resources to WAR-deployment-1 the target directory is hard coded to WAR-deployment-1. What if project-1 is part of build-deployment-2 and files have to be copied to WAR-deployment-2?! Can I use build properties for this? Or is the assembly plugin a solution?
Related
We have a Spring Boot app (exposing REST services) with multiple modules and for dev purposes we're using the default Spring Boot build approach - Maven builds it as one executable war file, that has Tomcat embedded into it.
For productive deployment purposes this doesn't work. We already have web app servers setup and we need a regular, non-executable war, that can be deployed on those servers. I already figured out, how I can build it.
We also will have another, related web apps (war files) deployed on the same productive servers (e.g. - simulator of the app). Of course, they will use (some of) the same modules, so the question it raises is how to setup maven to build the war and the module jars outside of it, so the other apps (war files deployed on the same server) could have dependencies on them. I couldn't find a good explanation/example how to do that.
Any ideas, links, blogs?
This is really more of a Maven question than Spring Boot. When you have a multi-module project Maven still creates individual artifacts for each module so you can still reference them as dependencies elsewhere.
For example in my setup with Spring boot I have the parent project and the modules underneath it. Most of the modules are jar artifacts, some with dependencies on other modules in the project and of course some external dependencies as well. By using the parent we can standardize some of the versions used in the dependencies using placeholders in the parent. Since the artifacts are still built and published separately you can reference them in other projects, which is what I believe you are asking.
For example (just the main tags and not all of them):
Parent:
<groupId>com.somecompany</groupId>
<artifactId>project-parent</artifactId>
<packaging>pom</packaging>
<version>1.1.2-SNAPSHOT</version>
<modules>
<module>module1</module>
<module>module2</module>
</modules>
Module1:
<parent>
<groupId>com.somecompany</groupId>
<artifactId>project-parent</artifactId>
<version>1.1.2-SNAPSHOT</version>
</parent>
<groupId>com.somecompany.tools</groupId>
<artifactId>project-tools-core</artifactId>
<version>1.1.2-SNAPSHOT</version>
<packaging>jar</packaging>
Module2:
<parent>
<groupId>com.somecompany</groupId>
<artifactId>project-parent</artifactId>
<version>1.1.2-SNAPSHOT</version>
</parent>
<groupId>com.somecompany.apps</groupId>
<artifactId>project-webapp</artifactId>
<version>1.1.2-SNAPSHOT</version>
<packaging>war</packaging>
<!-- dependency on other module -->
<dependency>
<groupId>com.somecompany.tools</groupId>
<artifactId>project-tools-core</artifactId>
<version>${project.version}</version>
</dependency>
Some Other Project:
<groupId>com.somecompany.apps</groupId>
<artifactId>project-webapp-services</artifactId>
<version>1.3.0-SNAPSHOT</version>
<packaging>war</packaging>
<!-- dependency on other module which is published -->
<dependency>
<groupId>com.somecompany.tools</groupId>
<artifactId>project-tools-core</artifactId>
<version>1.1.1</version>
</dependency>
So in this case assuming you had published version 1.1.1 of your parent and its modules you can have another project refer to any of those published artifacts. Maybe it is the release and publishing step you are missing.
Is there a way to have a single Spring Boot project be packagable into both JAR and WAR without changing the pom.xml or the application source?
I've read Converting a Spring Boot JAR Application to a WAR, but it converts the project to WAR and it loses the ability to be packaged as JAR.
I don't expect mvn package to do both. What I want is something like mvn i-want-a-jar and it would package the project as JAR. Or I could run mvn i-want-a-war and it would package the project as WAR.
Is this possible?
I managed to do it by adding
<packaging>${packaging.type}</packaging>
to the POM file and then setting different profiles for JAR and WAR:
<profiles>
<profile>
<id>jar</id>
<properties>
<packaging.type>jar</packaging.type>
</properties>
</profile>
<profile>
<id>war</id>
<properties>
<packaging.type>war</packaging.type>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
</profiles>
Now mvn package -P war produces a WAR and mvn package -P jar produces a JAR.
Another option is to create separate modules for JAR and WAR, but I didn't go that route.
What's wrong with a WAR file that's executable? Isn't that what you really need?
P.S. like
java -jar name.war
We've recently had a similar requirement, where an existing Spring Boot based project that was originally packaged as an executable Jar needed to support Tomcat and WildFly deployments.
Due to some dependencies used in this project (for example WebJars), a simple switch to WAR package wasn't an option since some of those dependencies were required for WildFly (VFS support) but not for other deployment.
The solution was to restructure the project modules in a way that core module contained the actual project but without having Spring Boot’s plugin applied, while several package modules would depend on core module and configure deployment artifact specifics (Boot and other plugins, deployment specific dependencies etc.).
That way project build was able to generate multiple deployment artifacts (Boot's executable JAR, traditional WAR and WildFly specific WAR) in a single build run.
In case anyone finds this useful, the sample project to demonstrate the approach is available on Github. The project can be built by either Gradle or Maven.
I have a EAR project that I want automatize the building process using maven exclusively.
The EAR project has
Standard jar modules
Web modules
EJB modules
RAR modules
To be able to execute the product in Jboss 4.2.3 and WebSphere 7 the EJB and RAR descriptors must be configured in different way. Also we have one jar library for each app server.
What I want is to be able to build one EAR for each apps server using the same projects, and for that I need
Include a JAR module depending of the app server
Use the customized descriptor in the EJB/RAR modules depending of
the app server
Package all this customized modules in an EAR
Can this be done using the same set of project in maven?
Sure. Have a look at profiles in maven. They allow you to adjust various things (from the link) like:
<repositories>
<pluginRepositories>
<dependencies>
<plugins>
<properties> (not actually available in the main POM, but used behind the scenes)
<modules>
<reporting>
<dependencyManagement>
<distributionManagement>
a subset of the element, which consists of:
<defaultGoal>
<resources>
<testResources>
<finalName>
The best is to create separate modules like ear-websphere, or ear-jboss and make an appropriate pom file which contains the needed configuration for maven-ear-plugin.
I have the following maven-setup:
parent-project
|- libraries
|- utilities
|- core
|- component1
|- component2
in the parent i define all dependency- and pluginmanagement and the infos about the dev-team. utilities containing functional artifacts like the website skin and checkstyle-config, libraries are bundle-artifacts for simplifying the dependencies. The site is build on the core-module and its sub modules. The parent-part of the core pom.
<parent>
<artifactId>parent</artifactId>
<groupId>my.group</groupId>
<version>3.0.0</version>
</parent>
<artifactId>core</artifactId>
<version>3.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
When staging or deploying the site, the page is located in a "core"-subdir (e.g. /target/staging/core/index.html). Is there a way to locate the site of core in the root?
Atm i use a "dirty hack". On the webserver i created a syslink with ln -s ./ core so he don't knows its the same dir.
Solution was, that maven generates that subdirectory only, when the url for deploying is inherited from the parent. All I need to do was move the distributionManagement section for site deploy and the url element from parent to core.
I'm working on a multi-project, and right now I have a structure that resembles this (actually there are a couple of jar projects and a couple of war projects)
/myProj
|_______projA (jar)
| |____pom.xml
| |____target/jar files
|_______projB (war)
| |___pom.xml
| |___web-inf/lib/jarfiles
|_______projEar
| |___pom.xml
|___pom.xml
What I want to achieve, is to make projA and projB to read their dependences from a common shared folder, instead of keeping their own copy.
Actually, I don't really care where they read them from at compile time, but when I package my EAR file, I want each jar/war to appear just once, hence reducing the EAR size.
I've tried declaring the dependencies on the parent pom, declaring the dependencies as and some other things, but so far I haven't achieved this.
Is there an easy way to achieve this? Any simple maven plugin?
Thanks in advance.
You should be able to do this by adding the JAR as a dependency to your EAR's pom.xml:
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>myapp-web</artifactId>
<version>1.0-SNAPSHOT</version>
<type>war</type>
</dependency>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>myapp-utils</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>jar</type>
</dependency>
</dependencies>
...and specifying the dependency as provided in your WARs' pom.xml:
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>myapp-utils</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
If Maven/other tooling has already copied the JAR to your WEB-INF/lib directory, you may need to delete the file manually prior to rebuilding.
This should result in an EAR of the form:
META-INF/MANIFEST.MF
lib/myapp-utils-0.0.1-SNAPSHOT.jar
META-INF/application.xml
myapp-web.war
When you are moving to Maven, you should not store the dependency JAR's in your code base. I would suggest you to create a central Maven repository which will contain all the dependencies.
Refer mvn install to first install these artifacts into the local repository. Also, you can refer to the maven central repository to get artifacts while building.
What you need to do is: remove all the dependency jar's from the source code, and all their dependency in the pom.xml. These would be downloaded and packaged from the maven central repository as and when required. Set the Dependency Scope of the artifacts accordingly.