Maven project for both WAR and standalone server/client - java

I have a POM-based Java project. It contains a number of servlets for deployment in a WAR. However, in addition to this, I also have classes that launch the application as a standalone using embedded servlet and database environments (for a turnkey development environment). Additionally, there is also a command-line client for the application.
I would like to have the ability to build the project into both the WAR and two separate executable JARS (one server, one client). I'm not concerned about the JARs/WAR containing some unnecessary code or deps- I just want all 3 to work.
What's the "correct" way to do this with Maven?

Multiple projects is the way to do this. Put the common code in the first project along with the standalone support. Then make a second with war packaging that depends on the first.

You could use assembly plugin to do this. Assembly plugin can package zip or tar.gz archive for you. It's a perfect distribution format for standalone applications. When you configure assembly plugin you could link it to package phase, so application will be packaged in two formats: war and zip.
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>assembly</goal>
</goals>
</execution>
</executions>
</plugin>

Related

Building executable from different jars

I wrote a program where various java library's used in the program. I made a jar file of my program using netbeans. Now if I use that jar on any other location, then I will have to manually include all the jar libraries.
Is there any way so that all the dependent libraries should get build with my program's jar to build a single jar instead of so many jar files ?
I know there are programs which converts jar to exe, they also do the same thing but I want to get the last file into jar format, so that it could also run on Linux.
Thanks
You can use use One-Jar
One-JAR provides custom classloader that knows how to load classes and resources from a jars inside an archive, instead of from jars in the filesystem. It discovers dependency jar files based on the internal structure of the archive, there is no custom code required to do this. One-JAR archives can be constructed using Ant or Maven2. Your application can be run using java -jar my-app.jar
Using Maven: you need to update the plugins section pom.xml:
<plugin>
<groupId>org.dstovall</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
<executions>
<execution>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
And update pluginRepositories section in pom.xml
<pluginRepository>
<id>onejar-maven-plugin.googlecode.com</id>
<url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
</pluginRepository>
When you will execute the mvn package you will get yourappname-one-jar.jar and you can run it java -jar yourappname-one-jar.jar
Yes it can be done. Since you are using Netbeans, this article may help you.
If you are using maven, this maven-shade-plugin is what you are looking for: https://maven.apache.org/plugins/maven-shade-plugin/

WSDL2CODE maven plugin

When using WSDL2CODE maven plugin, classes and resources are being created in target folder, I wanted them to be routed to src and resources folder in webapp, can you please help me in this regard?
Also I see ant config file build.xml being created along with the source and resources in the target folder, why this usually happens?
Please find my maven plugin below.
<plugin>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-wsdl2code-maven-plugin</artifactId>
<version>1.4</version>
<configuration>
<packageName>com.xyz</packageName>
<wsdlFile>src/main/resources/polupdates.wsdl</wsdlFile>
<databindingName>xmlbeans</databindingName>
<generateServerSide>true</generateServerSide>
<generateServicesXml>true</generateServicesXml>
</configuration>
<executions>
<execution>
<goals>
<goal>wsdl2code</goal>
</goals>
</execution>
</executions>
</plugin>
I am not good at maven, can you please share me some good guide with respect to web services development with maven.
why you want to put it in the source folder?
By convention, Maven automatically compiles any source files that it finds under the following directory:
target/generated-sources/
All the Java source file will be compiled along with the generated one and you can find them in the target/classes folder .Now when you package these all the classes along with the generated one will be ther in the packaging(jar/war)
If you are using an IDE such as Eclipse or Intellij's IDEA and having problem , you need to make sure that the IDE is aware of the generated Java code. For example, in Eclipse it is necessary to add the target/generated-sources/jaxws directory to the project as a source code directory.

Building JAR that includes all its dependencies

This is probably a really fundamental question, but I'm afraid I don't know much about Java and I couldn't find the answer anywhere.
I'm attempting to build an Ant library which depends on the TFS SDK. I followed the guide to setting up a project, but when I export it as a JAR and try to run a task using ANT I get the following error:
java.lang.NoClassDefFoundError: /com/microsoft/tfs/core/util/TFSUser
I realise I could put the TFS SDK JAR in my ANT lib folder, but if possible I'd like my JAR to include it and the library just work without having to do so.
This answer seems to say it's possible to include all the resources needed to run using Eclipse (I'm using 3.7.2) but it doesn't detail how to actually do it. What is the option in Eclipse to do so?
Select "Extract required libraries into generated JAR" as you do the export.
Select "Extract required libraries into generated JAR" as you do the export.
Use File -> Export -> Java -> Runnable JAR file instead from Eclipse.
The "Extract required libraries into generated JAR" should be what you need.
When you build a jar you get a JAR containing just your code, and not any dependencies your Jar requires. You could use something like jarjar to combine all the dependencies into one easy to manage Jar file or copy all the depend JARs into a folder for ease of use. It looks like Eclipse has options to also do this kind of thing (see posts above).
The other option would be to use a dependency management system such as Maven or Ivy. This has a higher learning curve, but for a library it is worthwhile as it will allow users of your library to easy grab all the dependencies. For an end user application then a single distributable is likely a better option (for which you could use Maven or Ivy to internally manage the dependencies and then something like jarjar or Java Web Start to distribute to your end users).
Just in case if you're doing with maven. You need to include following plugin.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<properties>
<property>
<name>listener</name>
<value>com.example.TestProgressListener</value>
</property>
</properties>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Read more # how do I build JAR file with dependencies?
You would need to depend on classpath attribute in manifest file. This explained well at How to package libraries into my jar using Ant

Distributing a jar

I'm distributing a jar file, with associated libraries, media, documentation, etc. I would like to create a simple deb/rpm package for linux users, and I would also like to distribute this for windows. What is the best way to go about setting up the jar to play nicely with debs? Every deb file I've looked at so far has been c/c++ with a makefile, which isn't at all helpful. How do I package my java jar for distribution?
Edit It would be nice if this could automate the placement of conf files in /etc/project-name/sample.conf, icons in /usr/share, etc.
The Maven 2 DEB Plugin can be used to produce a Debian package from any project that can be packaged as a JAR. Debian packages can be used on most Debian-based Linux Disributions including Ubuntu and Knoppix.
http://www.mojohaus.org/deb-maven-plugin/using-deb.html
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>deb-maven-plugin</artifactId>
<configuration>
<description>A test project</description>
<maintainer>Tim OBrien <tobrien#discursive.com></maintainer>
<section>libs</section>
<priority>optional</priority>
<architecture>all</architecture>
</configuration>
<executions>
<execution>
<goals>
<goal>deb</goal>
</goals>
</execution>
</executions>
</plugin>
...
This project might make it easier for you.
For packaging your Java application as a Debian package I would recommend jdeb. It's very flexible and integrates well with Maven and Ant.

Creating a self-contained source release with Maven

Up until now we used Ant in my company. Whenever we wanted to send the application to the client we run a special Ant script that packaged all our source code with all jar libraries and Ant itself along with a simple batch file.
Then the client could put the files on a computer with no network access at all (and not even Ant) and run the batch file. As long as the computer had a valid JDK the batch script would compile all the code using the jars and create a WAR/EAR that would finally be deployed by the client on the application server.
Lately we migrated to Maven 2. But I haven't found a way to do the same thing. I have seen the Maven assembly plugin but this just creates source distributions or binary ones. Our scenario is actually a mix since it contains our source code but binary jars of the libraries we use (e.g. Spring, Hibernate)
So is it possible to create with Maven a self-contained assembly/release/package that one can run in a computer with no network access at all??? That means that all libraries should be contained inside.
Extra bonus if Maven itself is contained inside as well, but this is not a strict requirement. The final package should be easily compiled by just one command (easy for a system administrator to perform).
I was thinking of writing my own Maven plugin for this but I suspect that somebody has already encountered this.
From your dev environment, if you include the following under build plugins
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
and invoke mvn assembly:assembly, you would get yourApp-version-with-dependencies.jar in the target folder. This is a self-sufficient jar, and with a Main-class MANIFEST.MF entry, anybody can double click and run the application.
You might try this approach:
Use mvn ant:ant to create ant build
scripts from a maven project
Make sure ant is a project dependency
Use the assembly to build an ant
system
or plan b:
Use mvn ant:ant to create ant build
scripts from a maven project
Make sure ant is a project dependency
Write a "bootstrap class" to call Ant and run the build
Use appassembler to build a
scripted build and install environment
In plan b, you'd write scripts to set up a source tree someplace from the packaged source jars, and then use the appassembler build bat or sh scripts to call the bootstrap and build via ant. Your bootstrap can do anything you need to do before or after the build.
Hope this helps.
Perhaps an answer that I submitted for a similar question could be of some assistance. See Can maven collect all the dependant jars for a project to help with application deployment? The one piece missing is how to include the source code in the assembly. I have to imagine that there is some way to manage that with the assembly plugin. This also doesn't address the inclusion of Maven in the distribution.
What was the reason for moving from Ant to Maven? It sounds like you had everything worked out well with the Ant solution, so what is Maven buying you here?
If it is just dependency management, there are techniques for leveraging Maven from Ant that give you the best of both worlds.
the source plugin will give you a jar containing the source of a probject "source:jar". you could then use the assembly plugin to combine the source jars from your internal projects (using the sources to reference these source jars) and the binary jars from the external projects into one distribution.
however, as for turning this into a compilable unit, i have no suggestions. you could certainly bundle maven, but you'd need to create a bundle containing all the plugins you need to build your project! i don't know of any existing tool to do that.
This is how I do it... on the build part of the pom add in this:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
And then on the profiles section add this bit in:
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
And when I do a maven install it builds the jar and also checks in a jar of the source.

Categories