Automatically download and run standalone Java app from Maven - java

I would like to have an application/script that I could use to execute a stand alone Java application (i.e. a basic class with a main method) from a given Maven artifact. Based on my research nothing like this currently exists, but I thought I'd ask the question to the community and see if anyone knows of a project that could support my needs.
The idea would be that I would pass in, either via a config file or the command line, a Maven artifact spec (group ID, artifact ID, and version) along with a fully qualified class name and a list of arguments. The given artifact and all of its dependencies would then be downloaded (or not if they're already in the local repo) and the application would be launched with the appropriate classpath.
At this point I don't think it will be too difficult to implement a system that does this using the Aether library and Java's ProcessBuilder, but I was wondering if anyone else knew of an existing project that already handles this before I start reinventing the wheel.

Perhaps this is obvious, but why wont the exec plugin work? http://mojo.codehaus.org/exec-maven-plugin/
mvn exec:java -Dexec.mainClass=com.project.App
If com.project.App were part of another jar, you would include it as a dependency like you normally would.

Running an application using Maven is pretty simple. I wonder if this something that you are looking at or did I get the question wrong?
mvn exec:java -Dexec.mainClass="com.test.foo.Main" -Dexec.args="arg1 arg2..."

I have just pushed to Maven Central the Installation plugin. It allows installing and executing artifacts from repositories and it doesn't require a project.
It's very similar to package managers like yum, apt or gem:
mvn installation:install -Dartifact=groupId:artifactId
This will create a shortcut to your class available on the path.

Related

Best way to turn in a java project: Maven vs Simple java project

Here is my situation: I am turning in a coding challenge for an interview. We are allowed to use any programming language, I chose Java. I completed the project and it provides the correct output, but I am stuck on some technicalities of turning it in. The spec says that it will be compiled and run using the terminal on a mac or linux machine, and it says to "turn in source code only, please do not include compilation artifacts or binary dependencies". I have a couple jars as dependencies. Does this mean I can't include them with my source code? How would they compile the program then. Right now I am not using any management tool. I could use Maven and declare the dependencies in the pom.xml, but then I have to assume whoever grades my solution has Maven installed to run "mvn".
Should I stick with a basic java project and include the jars, use Maven instead, or is there another better way to do this? Sorry if I am overthinking this, I want to make it simple to run my project so my work can be assessed for its accuracy, not how I packaged it.
Yes, you can't include any dependencies as JARs. You need to use Maven or Gradle for this.
You don't need to assume that Maven is installed, Maven Wrapper can be used instead.
You can provide mvnw, what stands for maven wrapper. It's project-local installation of maven that is treated as source code and is used by calling ./mvnw instead of global mvn command (to make it working for the first time, use mvn -N io.takari:maven:wrapper). Reference.

Two Maven basics / requirements and first project questions

I want to use Maven for building my next Java Project.
So I have some questions about Maven before starting right off.
Does Maven need to be installed? Or can Maven binaries just be copied to a system (Windows) and be used in the same way.
Setup a Maven project required?
From a Maven tutorial i've seen that the first step in Maven is to setup a Maven project like this:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
Why is that? Is writing a POM file not enough when I only want to compile some Java files and include some jars?
Question 1 (Installation):
Well it mostly is simply copy, add to path, and run.
However in real world there is a bit more than that. For example,
- in a company, you may want to have a company central repository proxy. You will need to do extra set up in either HOME/.m2/settings.xml or MVN_DIR/conf/settings.xml (Wish I remember the path right :P )
You may want to put local repository in a different directory in some case, you will also need to change settings.xml.
In order to have building of big project works, you may need to adjust M2_OPTS environment variable.
etc...
All these things are extra manual installation work you may need (Not difficult though)
Question 2 (Archetype):
You are actually right. You can simply write your own pom.xml and forget about archetype (That's what I was doing in the past too :) ). You can think Archetype as some template-project-generation feature, so that you may generate some pre-defined project types, and the essential project directory structure, required dependencies and settings in POM are all done for you. Of course you may even provide your own archetype, so new projects in your company can make use of them to conform with guideline or standard you want.
Does Maven need to be installed? Or can Maven binaries just be copied to a system (windows) and be used in the same way.
Maven comes bundled as a zip archive that you just need to unzip. You then need to add the bin directory to the PATH environment variable and you are good to go.
Setup a Maven project required? From a Maven tutorial i've seen that the first step in Maven is to setup a Maven project like this:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
There are multiple ways to create a Maven project. However, it is important to remember that a Maven project only comes down to having a single pom.xml file. This file will be located at the root of your project. So you are right when you say that "writing a POM file is enough".
Now, since Maven is a tool that is built under the convention-over-configuration principle, several utilities have been created to help adhere with the basic conventions of Maven. One of those utilities is the maven-archetype-plugin, which is invoked by the call to mvn archetype:generate. This utility will create a basic pom.xml file along with the standard directory layout.
If you are using an IDE, you could also create a Maven project by using the corresponding Maven plugin of this IDE (for example for Eclipse, this is the M2Eclipse plugin).
Answer to 1st question:
Maven is available in distributed binary format.You just have to download it and extract it in your local machine. And then, you have to create one user variable named M2_HOME(sometime M2_OPTS is also required) and add it to PATH variable. That's all you need to set up basic needs.
If your system is inside some proxy network then you have to perform one additional settings. That is to copy secuirity xml, which is available inside the downloaded files, and modify the elements values inside it according to your network.
Answer to 1st question:
For the 1st time you need to use the command you specified. Once you get the file-structure, you may reuse it based on your need. But remember to follow predefined file-structure else you would be surely in a trouble.
However,it's always advisable to create the projects using maven command as it would do many things for you which you might have to do manually if you opt for manual maven project creation.

Maven builds on file changes

Is there anything already out there that would help with either / both of following?
Perform a Maven install when a file within that module changes
Perform a Maven install on the module and its dependencies if they have changed
I'm pretty sure I've heard of a Maven option to build dependencies as well but struggling to find anything from Googling...
Perhaps this isn't going to be Maven specific but instead involve a file watching tool that is OS specific, if so I would be interested in hearing about tools for Windows (XP).
Even though the answer comes late, I was looking for the same thing and I found https://github.com/rzymek/watcher-maven-plugin. Maybe someone else will be looking for the same thing.
I tried #Adrian's solution, but I couldn't get it working.
I found this maven package, https://github.com/fizzed/maven-plugins#watcher-fizzed-watcher-maven-plugin, that will watch for file changes, and I was able to get it working pretty quickly.
To building a module and its dependencies, use:
mvn -pl :module -amd
Automated builds are usually triggered from a version system like subversion or git.
Then you can use continuous integration tools like Jenkins.
There's also mvn reactor:make-scm-changes, which detects what modules have local changes vs. the configured scm system.

Using maven to produce production ready output

I have a muti-module maven project, and I created a new module that depends on 3 other modules. (I already have a web app maven module that produces a .war file, now I need this)
This module's output is a .jar, and it has a few resources also which are:
spring context xml file
properties file
Now I want to produce a production ready folder so I can upload it to my server. I am hoping maven can do this for me.
I need the following layout:
myjar.jar
/libs/ (the 3 other maven modules that are dependancies)
/resources
Also, there are some generic dependancies that my parent pom.xml have like slf4j/log4j/ that I also need to package.
It would be cool if I could add a switch to mvn that will produce this like:
mvn clean install production
I plan on running this on my server via the command line.
I think what you are looking for is a Maven Assembly:
https://maven.apache.org/plugins/maven-assembly-plugin/
You can use profiles to disable the generation of the assembly by default (can speed up the development process).
#puce is right in that you may be best to use the Assembly Plugin. What you can't do easily is add another lifecycle 'production' to maven. If you have time you could write a plugin to do this, but you might be better off using a profile called 'production' or 'prod-deploy' to enable the coping into place on the server.
mvn clean install -Pprod-deploy
One thing to remember with maven is that it is very good at building projects in using it's conventions, but it is pretty bad at actually script things to happen out side of the build lifecycle.
I have on several occasions used external scripting tools such as ant/python/bash and groovy to first run the build using mvn then to script the deployment in a more natural language.
The intention of Maven is building not deployment in the sense to production. For this purpose i would recommend things like Chef or Puppet. From a technial point of view it's of course possible to handle such things via Maven. What also possible to build on CI solution like Jenkins. Furthermore it's possible to run a script from Jenkins to do the deployment on production.

Good way to "wrap" jars for OSGi with Maven

I was looking at the PAX tools on OPS4J for example: this one and I thought I'd found a nice way to:
Specify an artifact
Create an assembled jar (jar that contains all dependencies) from that jar and its transitive dependencies
Wrap it with BND to create an OSGi bundle
It turns out, that I was wrong - it doesn't appear that the PAX stuff does this. (RTFM, right? :) )
But this got me wondering: is there something out there that does what I'm asking?
I've thought maybe I could do this by creating a simple POM and using the maven-bundle-plugin but this seems like it might be a bit cumbersome for what I'm asking.
NOTE: I get that embedding and assembling jar's is not really "the OSGi way" - so I wouldn't do this unless I really felt it useful. For example - Spring.
Thanks in advance.
I wrote a maven archetype that will help you wrap a jar as an OSGI bundle.
Let's say you want to wrap commons-collections version 3.2.1
First get the archetype and install it
git clone git://github.com/HallwayTech/maven-wrap-jar-archetype.git
cd maven-wrap-jar-archetype
maven install
Then use the archetype to start your project.
mvn archetype:create \
-DarchetypeGroupId=com.hallwaytech.osgi \
-DarchetypeArtifactId=wrap-jar \
-DarchetypeVersion=1.0-SNAPSHOT \
-DgroupId=commons-collections \
-DartifactId=commons-collections \
-Dversion=3.2.1
cd commons-collections
mvn install
To deploy to a Apache Sling inside of Felix run:
mvn install -Pdeploy
You have to maintain a local POM to get this done. There's not a utility that will take in a library/jar and spit out the appropriate OSGi MANIFEST in a jar. ServiceMix, along with Spring, have a lot of things already bundled up that you can use as examples. Two such examples I suggest looking at are:
commons-io - simple library wrapper
OpenJPA - wraps the main jar and brings in the dependencies with it
We do something similar to what you are describing. For example, we have an internal version of Apache QPid. It comes as 6 jars (client, core, common, backports, etc) which you would rarely use individually. We have one POM with BND which takes all the jars, and makes one uber-osgi-jar from them.
Steps:
Declare your dependencies (we have the jars, so we declared them as system deps.)
Import build plugin maven-bundle-plugin (2.1.0)
Set correct instructions for export, private and import packages
Execution of 'wrap' goal at 'package' phase
I tried The accepted answer and Erik's answer. Erik's suggestion was simple and worked right out the box. Although, it seemed to produce a huge MANIFEST in my case, and then I recalled the p2-maven-plugin. This last method works very well in a large number of cases. If the artifact you need is already bundle, or its dependencies are bundles it simply puts them into the repo it builds. If not, it will run maven-bundle-plugin with some default settings (or you can configure the settings you need). Very cool!
I especially like that it grabs the transitive dependencies and takes care of those too. If you don't need the repo, but are just after the wrapped bundle, it is a simple matter to go cherry pick it out of target/repository/plugins folder.

Categories

Resources