Autowiring of Spring Data Repo fails with Maven Skinny war option - spring

My question is similar to this one posted a while ago
The autowiring of Spring Data Repos fail when the external libraries are in EAR's lib folder.
The wiring works fine when all jars are included in WEB-INF/lib.
I tried setting the 'skinnyWar' to false but this is duplicating the jars in both EAR and WAR.
The application uses Spring Batch Admin 1.2.2 and Spring Data 1.1 with Spring 3.2.2 based.
Maven Version used is 3.3. The runtime is Websphere 7.x
I have another application that works perfectly fine with skinnywar set to true - this uses spring-ws, spring-data 4.0.x version.
The WAR POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>batchadmin-web</artifactId>
<parent>
<groupId>com.xyz.interfaces</groupId>
<artifactId>batch-parent</artifactId>
<version>1.0.BUILD-SNAPSHOT</version>
<relativePath>../batch-parent/pom.xml</relativePath>
</parent>
<packaging>war</packaging>
<name>Batch Admin Interface Web</name>
<dependencies>
<!-- Application specific jars/modules Not included for brevity-->
</dependencies>
<build>
<finalName>springbatch-admin</finalName>
<outputDirectory>${project.basedir}\src\main\webapp\WEB-INF\classes</outputDirectory>
<testOutputDirectory>${project.basedir}\src\main\webapp\WEB-INF\classes</testOutputDirectory>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
<packagingExcludes>WEB-INF/lib/spring-beans*.jar</packagingExcludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
The EAR POM content:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>batchadmin-ear</artifactId>
<parent>
<groupId>com.xyz.interfaces</groupId>
<artifactId>batch-parent</artifactId>
<version>1.0.BUILD-SNAPSHOT</version>
<relativePath>../batch-parent/pom.xml</relativePath>
</parent>
<packaging>ear</packaging>
<name>Batch Admin Interface</name>
<dependencies>
<dependency>
<groupId>com.xyz.interfaces</groupId>
<artifactId>batchadmin-web</artifactId>
<type>war</type>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<finalName>SpringBatchEAR</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<skinnyWars>true</skinnyWars>
<defaultLibBundleDir>lib/</defaultLibBundleDir>
<modules>
<webModule>
<groupId>com.xyz.interfaces</groupId>
<artifactId>batchadmin-web</artifactId>
<contextRoot>/springbatch-admin</contextRoot>
<bundleFileName>springbatch-admin.war</bundleFileName>
</webModule>
</modules>
</configuration>
</plugin>
</plugins>
</build>
Update: Since the EAR has only one Web module, used 'Single class loader for application' for 'WAR class loader policy' in the Websphere. This way, I am able to make this work.
I would like to know how to make this work without changing the classloader option as this might not be preferred when multiple web modules are present.

Related

spring-boot-maven-plugin not pulling in dependent classes into jar

Im having a problem with the spring-boot-maven-plugin whereby it is not including the dependent classes in the resulting jar file.
In the docs, it states that dependencies with scope provided will be included in the jar file, but I cant get it to include them.
I have a project with 2 sub-modules: model and restServer. In the model module, I want to use swagger to codegen based on an openApi input model. The resulting classes are put in a jar file: model/target/rest-model-0.0.1-SNAPSHOT.jar.
In the restServer module, I have the Spring RestController and Application java code, and want to "pull in" the model classes into the resulting jar file: restServer/target/rest-server-0.0.1-SNAPSHOT.jar with the spring-boot-maven-plugin builder, but its not including anything from the model sub-module.
The entire project structure and pom files are listed below.
How can I get the spring-boot-maven-plugin to pull in the class files from the model sub-module, effectively creating a "fat" self-contained jar?
Project Structure
project-root/
pom.xml # parent pom
model/
pom.xml
src/main/openApi/model.json
target/
generated-sources/* (package: com.me.rest.model.*)
rest-model-0.0.1-SNAPSHOT.jar
restServer/
pom.xml
src/main/java/com/me/rest/
controller/Controller.java
Application.java
Parent pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
</parent>
<groupId>com.me</groupId>
<artifactId>rest-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>rest</name>
<packaging>pom</packaging>
<description>Swagger codegen for Spring Rest Server sandbox project</description>
<scm>
<connection>scm:git:git#github.com:swagger-api/swagger-codegen.git</connection>
<developerConnection>scm:git:git#github.com:swagger-api/swagger-codegen.git</developerConnection>
<url>https://github.com/swagger-api/swagger-codegen</url>
</scm>
<prerequisites>
<maven>2.2.0</maven>
</prerequisites>
<modules>
<module>model</module>
<module>restServer</module>
</modules>
</project>
model/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.kontron</groupId>
<artifactId>rest-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>com.kontron</groupId>
<artifactId>rest-model</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies> ... </dependencies>
<build>
<plugins>
<!-- Swagger codegen plugin -->
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration> ... </configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
restServer/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.kontron</groupId>
<artifactId>rest-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>rest-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.kontron</groupId>
<artifactId>rest-model</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>provided</scope> <!-- Notice scope is provided -->
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.1.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Update: adding resulting META-INF/MANIFEST.MF:
Manifest-Version: 1.0
Implementation-Title: rest-server
Implementation-Version: 0.0.1-SNAPSHOT
Built-By: bjohnson
Implementation-Vendor-Id: com.me
Spring-Boot-Version: 2.1.2.RELEASE
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.me.rest.Application
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Created-By: Apache Maven 3.5.4
Build-Jdk: 1.8.0_144
Implementation-URL: https://projects.spring.io/spring-boot/#/spring-bo
ot-starter-parent/rest-parent/rest-server
The dependencies are placed in BOOT-INF\lib\ of the repackaged JAR file.
This path will be added to the classpath of you Spring Boot Application.

Get war module when running the parent maven project

Is there a way to run a war module automatically when I run the parent project?
To make it clear, I did three separate maven project (db, core and presentation), then I made a parent project which include the 3 projects mentioned before.
I'd like to get the presentation module running when I run the parent project.
Also, I want to know if it's possible to save the hole work from the parent project to my git account.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.project.xxxxxxx</groupId>
<artifactId>parent-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>parent-project</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<targetJdk>1.7</targetJdk>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0</version>
<configuration>
<port>8080</port>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${targetJdk}</source>
<target>${targetJdk}</target>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
</plugins>
</build>
<modules>
<module>../project-db</module>
<module>../project-core</module>
<module>../project-presentation</module>
</modules>
<dependencies>
</dependencies>
</project>
You need to specify the sub-project under tag.
You may refer http://books.sonatype.com/mvnex-book/reference/multimodule-sect-simple-parent.html for example
Your modules should be unter your parent in the file structure. Like
parent-project
pom.xml
project-db
pom.xml
project-core
pom.xml
project-presentation
pom.xml
Then you have to change the parent pom:
<modules>
<module>project-db</module>
<module>project-core</module>
<module>project-presentation</module>
</modules>

How to package EAR for GlassFish with Maven?

I want to package one EAR that will be deployed on GlassFish Server Open Source Edition.
Here are the relevant parts of the pom.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
....
<packaging>ear</packaging>
<dependencies>
....
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>2.8</version>
<configuration>
<version>6</version>
<defaultLibBundleDir>/lib</defaultLibBundleDir>
</configuration>
</plugin>
</plugins>
</build>
</project>
I usually run mvn compile and mvn package in the command terminal. The resulting EAR has the following structure.
EAR/lib/*.jar
EAR/META-INF/application.xml
EAR/META-INF/META-INF.MF
EAR/META-INF/maven/...
The application.xml is
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" version="6">
<display-name>test-app</display-name>
<library-directory>/lib</library-directory>
</application>
If I try to run asadmin deploy test-app.ear to deploy the EAR to GlassFish I get this error.
remote failure: Error occurred during deployment: org.xml.sax.SAXParseException; lineNumber: 4; columnNumber: 22; Deployment descriptor file META-INF/application.xml in archive ....
Here I rename application.xml to glassfish-application.xml and change its content to
<!DOCTYPE glassfish-application PUBLIC "-//GlassFish.org//DTD
GlassFish Application Server 3.1 Java EE Application 6.0//EN"
"http://glassfish.org/dtds/glassfish-application_6_0-1.dtd">
<glassfish-application>
<unique-id>67488732739338240</unique-id>
</glassfish-application>
If I rerun asadmin deploy test-app.ear GlassFish recognizes the deployment descriptor but throws the next error that says Application [test-app] contains no valid components.
Here I move all jars from EAR/lib/*.jar to EAR/META-INF/lib/*.jar.
If I now rerun asadmin deploy test-app.ear GlassFish recognizes the EAR as valid and deploys it.
Since I dont want to manually change the EAR every time. How can I configure Maven to
1. Output a valid application.xml or glassfish-application.xml
2. Copy the dependencies not to EAR/lib/ but to EAR/META-INF/lib (if it is really necessary)
Thanks in advance.
How can I configure Maven to
Output a valid application.xml or glassfish-application.xml
Copy the dependencies not to EAR/lib/ but to EAR/META-INF/lib (if it is really necessary)
application.xml can be autogenerated by maven-ejb-plugin and for the simple test I would leave it up to plugin
for dependencies copying - it depends what you package in your ear (can be war/jar/...) but in general, it's a good idea, to let maven do it. For the purpose you miss in your pom.xml sections that would refer to modules (war/jar/...) you want to be included in there
moreover I don't see a reason for non-standard libs folder you specified with: <library-directory>
So I'd go for config like the sample present here.
To include the relevant sections in answer:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>2.8</version>
<configuration>
<version>6</version>
<modules>
<webModule>
<groupId>com.mycompany</groupId>
<artifactId>myWar</artifactId>
<bundleFileName>myWarNameInTheEar.war</bundleFileName>
<contextRoot>/myWarConext</contextRoot>
</webModule>
<ejbModule>
<groupId>com.mycompany</groupId>
<artifactId>myEjb</artifactId>
<bundleFileName>myEjbNameInTheEar.jar</bundleFileName>
</ejbModule>
</modules>
<displayName>My Ear Name displayed in the App Server</displayName>
<generateApplicationXml>true</generateApplicationXml>
</configuration>
</plugin>
</plugins>
</build>
<!-- Define the versions of your ear components here -->
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>myWar</artifactId>
<version>1.0-SNAPSHOT</version>
<type>war</type>
</dependency>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>myEjb</artifactId>
<version>1.0-SNAPSHOT</version>
<type>ejb</type>
</dependency>
</dependencies>
Please note you need to specify dependencies - for modules, but include those in modules section as well, to have them packaged.
Feel free to ask in case of any further questions.

Create multi-module project in maven

I'd like to create multimodule standalone application with maven.
In my case I'd like to make 'Loader' project (.jar) contains all other projects. But now I have just set of .jar files (loader.jar, crawler1.jar ... etc)
loader's .pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.javanix.jmetalcrawler</groupId>
<artifactId>loader</artifactId>
<version>1.0</version>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
subproject's .pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.javanix.jmetalcrawler</groupId>
<artifactId>Crawler-1</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>com.javanix.jmetalcrawler</groupId>
<artifactId>loader</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
parent's .pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.javanix.jmetalcrawler</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<name>jMetalCrawler</name>
<modules>
<module>Crawler-1</module>
<module>Loader</module>
</modules>
</project>
Lifecycle:
compile 'Loader' (has interfaces/abstract classes)
compile/package 'crawler1' (as it depends on 'Loader' project)
compile/package 'crawler2' (as it depends on 'Loader' project)
package loader with compiled 'crawler' projects
P.S.:
Thanks to Adrian Shum , he gave an idea to make my project clearer
After restructure my project in 'Launcher' project we can add
dependencies via maven-assembly-plugin (#see http://rombertw.wordpress.com/2010/05/14/maven-recipe-building-an-aggregate-jar/)
I'd suggest project structure like this:
loader (POM, multi-module)
+ loader-api (JAR)
+ crawler1 (JAR, depends on loader-api)
+ crawler2 (JAR, depends on loader-api)
+ loader-app (JAR, depends on loader-api, crawler1, crawler2.
The standalone app is built here)
By splitting the API that crawlers depends and the app itself, the whole project structure is much easier to manage. And, it is more modularized too, as we are no longer mixing the API with the app
If you by "multimodule standalone application with maven" mean a self-contained, executable jar that contains all its dependencies then onejar-maven-plugin may be what you are looking for. See the documentation for usage examples.

Maven descriptor (META-INF/maven) duplicate entry in archive

I'm facing a problem with maven build. I have several ejb projects. After maven build the jar-file contains the maven descriptor in META-INF/maven twice, i.e. if I extract files to disk 7zip asks to overwrite files although extracted to a new folder. If a specify <addMavenDescriptor>false</addMavenDescriptor> in the archive-tag of the ejb plugin then the maven decriptor is still generated but only once. Is there another place where I can disable maven descriptor generation or does anybody know the reason for the duplicate generation?
Maven version is: 3.0.3
Project structure is like:
-pom
-ejb
Here is the pom.xml of the EJB module:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>TestMavenDescriptors</artifactId>
<groupId>de.test</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>TestEJB</artifactId>
<packaging>ejb</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ejb-plugin</artifactId>
<version>2.3</version>
<configuration>
<ejbVersion>3.1</ejbVersion>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
Here is the pom.xml of the parent project.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.test</groupId>
<artifactId>TestMavenDescriptors</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>TestEJB</module>
</modules>
</project>
I found out that this is a problem special to eclipse version (I have RAD 8 trial) and possibily of the m2e plugin version. The above behavior (duplicate generation of maven descriptors) occurs only if I have the EJB project in my workspace added. That means if I remove the EJB project from workspace (without deleting contents on disk) such that only the hierarchal parent maven project (pom packaged) is existing in the workspace (which contains the EJB project but EJB project is then not known to eclipse) then everything works fine. Strange, isn't it?!
BTW: on current eclipse (java ee package) this doesn't occur, all fine there.

Resources