How to package EAR for GlassFish with Maven? - 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.

Related

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>

Intellij cant resolve tagsoup namespace even if maven dependency added

I had a problem with TagSoup in one of my projects: even if I added maven dependency to pom, IntelliJ 13 Ultimate would still shout that it can't resolve namespace org.ccil.cowan.tagsoup.Parser (pointing at "ccil" bit).
So I have created a new, empty Maven project, and added 2 dependencies to it: saxon9 and tagsoup1.2.
<?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>MavenExperiment</groupId>
<artifactId>MavenExperiment</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.ccil.cowan.tagsoup</groupId>
<artifactId>tagsoup</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
<version>9.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
</plugin>
</plugins>
</build>
</project>
And created simple class:
public class MavenExperiment {
net.sf.saxon.TransformerFactoryImpl impl;
org.ccil.cowan.tagsoup.Parser pars;
}
The outcome:
both saxon and tagsoup are being downloaded to my local repo
it builds in the terminal (mvn clean install)
in IntelliJ the saxon stuff is being resolved alright
in IntelliJ the tagsoup stuff is still throwing up on the "ccil" part of the namespace with error "cannot resolve symbol"
won't build in IntelliJ because of the above error
Any ideas? Am I missing some kind of dependency for tagsoup (certainly can't see anything on the tagsoup website about such dependency)? Thanks.

Using a variable in Maven from the super pom

I am giving myself a crash course in Maven and stumbled across a great plugin called buildnumber: http://www.mojohaus.org/buildnumber-maven-plugin/create-mojo.html
I have setup a VERY rudimentary, beginners project and in the pom.xml file I am successfully having the ${buildNumber} to interpolate.
I have the pom.xml below (I apologize for the length of it).
<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>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>my-app</name>
<url>http://maven.apache.org</url>
<scm>
<connection>scm:git:ssh://git#bitbucket.org/XXXX/bb101repo.git</connection>
<developerConnection>scm:git:ssh://git#bitbucket.org/XXX/bb101repo.git</developerConnection>
<url>https://bitbucket.org/XXXX/bb101repo.git</url>
</scm>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
<configuration>
<shortRevisionLength>5</shortRevisionLength>
<!-- doCheck : Check for locally modified files. If true build will fail if local modifications have not been commited -->
<!-- doUpdate : Update the local copy of your repo. If true the plugin will update your local files with the remote modifications before building -->
<doCheck>true</doCheck>
<doUpdate>false</doUpdate>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}-${project.version}-${buildNumber}</finalName>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
When I run mvn package, it works as intended.
I have another file in my project (under src) called info.xml and it's below.
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>FMS Help</display-name>
<version>${buildNumber}</version>
</web-app>
How do I get the ${buildNumber} to unpack in my tag under target?
I'm guessing it's a really simple solution, but I'm stumped. Again, I'm a complete n00b at Maven and any pointer in the right direction would be appreciated.
JW
You need to tell Maven to apply filtering to your resources. Check out the resources plugin documentation here:
http://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
To avoid applying filtering to all your source files, you'd either need to set up the proper include/exclude paths or move the info.xml file to the resources directory.

Autowiring of Spring Data Repo fails with Maven Skinny war option

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.

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