Creating a self-contained source release with Maven - java

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.

Related

Automatically install a project in the local repository?

I'm trying to work around a maven bug MDEP-187 ( https://issues.apache.org/jira/browse/MDEP-187 ) by not using workspace resolution.
This forces me to do a mvn install for all my dependencies, I'm doing this by creating a launch configuration in eclipse with goal install.
The problem is that i have to create a launch config for every project in my multiproject workspace, in addition to install i have to manually call every launch config and run it. Which just doesn't work.
Is it possible to automatically install a project in the local repository? (whenever i update my code)
If you don't need to run dependency:copy in Eclipse, you can use following work-around:
Add a profile to your pom.xml, something like this:
<profiles>
<profile>
<id>copy</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
[...]
</executions>
</plugin>
</plugins>
<build>
<profile>
</profiles>
Enable workspace resolution in Eclipse.
Then Eclipse will not use dependency:copy, but you can use dependency:copy with command line: mvn install -P copy.
I did go with #khmarbaise solution:
But than you need to can handle the whole thing via
maven-assembly-plugin which can create archives / folders with all the
dependencies. Apart from that a swing ui must be started somehow which
will need some kind of shell script / batch file which you can create
by using appassembler-maven-plugin...And it sounds like you need to go
for a multi module project in maven..cause you might have parts like
core, ui, etc. which are needed to be combined in the end.
#khmarbaise i was in the understanding that the assembly-plugin didn't
support putting dependencies in a lib/ folder (just putting everything
in 1 big jar), but after a little bit of trying i just go myself a zip
with a runnable jar and my dependencies in a lib/ folder. Tomorrow i'm
going to read a bit more about the assembly-plugin. I'm happy ;-

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.

How to generate java doc and sources for a library created by me using maven

This might be small question but I am not able to find answer to it. I wrote a library called Utilities and used java doc style comments. Using maven (m2e plugin in eclipse). I am using maven install option. I am getting a jar file and i am pushing the jar file to a central repository and reusing the same library in another project. I am able to use the lib and complete my project successfully but when I do ctrl click I am not able to see the library code from my project. I am also not able to see the arguments description when i hover my mouse on the methods.
I know that it is because My project is not finding sources and java doc .
So How can i generate sources , java doc for my library and attach them to my project using maven.
Thanks
See:
Cookbook: How to attach source and javadoc artifacts?
You need to use the maven sources plugin found at this link:
http://maven.apache.org/plugins/maven-source-plugin/usage.html
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
You must deploy sources and javadoc JARs along with library JAR. AFAIR you can either use:
$ mvn clean javadoc:jar source:jar deploy
or:
$ mvn clean deploy -DperformRelease=true
See also:
How to deploy Javadoc jar file?
Maven 2: Deploying Javadoc with your project
Maven 2: Deploying Project Sources
Attaching javadocs and sources to Maven install/deploy

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

Categories