Maven: How to generate a standalone application? - java

I am using Maven to manage a console application project. On my machine, I type mvn exec:java and Maven handles everything. What I want is, however, to execute the same application on a different machine without the help of Maven.
In NetBeans, Ant projects have a dist directory with all the necessary files. All you have to do is to type java -jar dist/App.jar. How can I make Maven generate such distributable directory or archive?
PS: Although seems relevant, this is not a duplicate of Create a standalone application with Maven.

I have used in maven.
http://mojo.codehaus.org/appassembler/appassembler-maven-plugin/
The Application Assembler Plugin is a Maven plugin for generating scripts for starting java applications. All dependencies and the artifact of the project itself are placed in a generated Maven repository in a defined assemble directory. All artifacts (dependencies + the artifact from the project) are added to the classpath in the generated bin scripts.
and http://maven.apache.org/plugins/maven-assembly-plugin/
The Assembly Plugin for Maven is primarily intended to allow users to aggregate the project output along with its dependencies, modules, site documentation, and other files into a single distributable archive.

You can build an executable jar file with the maven-jar-plugin; more info on their examples page here: http://maven.apache.org/shared/maven-archiver/examples/classpath.html
That will simply create an all-in-one jar that can be executed through java -jar

Related

Is there a plugin or framework that converts java web app war to maven war (pom.xml and mvn install command)?

Is there a plugin or framework that converts a java web application (war) into a maven project (pom.xml and mvn install command jar)? Thanks
EDIT An alpha java program that converts a jar's list into a maven project (pom.xml and mvn install command jar) is:
https://github.com/sunrelax/jar2mvn
The groupId for the artifacts is not even in the manifests within the jars in the lib folder so the research to fit version+groupId is quite complex.
Also, the way the package is generated (war-plugin) and the specific folders the original files are located can't be deducted.
ONLY in the case you decide to pass all the standards, and keep your own repository (with your own groupIds), maybe will be possible to auto-assign from jars version own-generated-groupId... but it's not worth it, later it would be difficult to maintain.
Better, and talking about third part libraries, take the jars one by one and hopefully you will have the version in the manifest and locate them in public repositories.

how does a Java program find its Maven packages?

I have a Java program in IntelliJ which has a pom.xml and uses Maven. The packages were downloaded and currently they are found by IntelliJ.
I'm a little confused though because the Maven repository is not part of the CLASSPATH as far as I can tell. So does IntelliJ just do a bit of magic where it looks into its Maven repository to find the packages? (I think that IntelliJ has its own Maven repo. I separately have Maven 3 installed, but I think it isn't using it.)
But more generally: If you build a JAR using Maven then I guess it will put the dependencies in the JAR where the Java program can find them, so there won't be a problem. But if you just run a Java program directly, do you need to add the Maven repository to your classpath or does something else happen?
Thanks for any information you can provide to lessen my confusion :)
When you start the program from IntelliJ using a runtime configuration for your main() method IntelliJ constructs the classpath from all the project dependencies. You can see this in the Run window, the first log line is the java command used to start the main(). It's a long line but it usually looks similar to:
java -javaagent:/opt/idea/idea-IC-173.3727.127/lib/idea_rt.jar=40165:/opt/infra/idea/idea-IC-173.3727.127/bin -Dfile.encoding=UTF-8 -classpath /home/ [...]
IntelliJ constructs the -classpath argument adding both the module target directory and the Maven dependencies referenced from the local Maven repository.
When you package the project using Maven mvn clean package usually it becomes a standalone JAR with just your code (unless you changed the defaults). Now you have a few choices how to provide dependencies needed to start your main():
Provide them using -classpath parameter just like IntelliJ.
Add maven-shade-plugin and use shade goal to the build a runnable Uber JAR. This creates a fat JAR which doesn't require -classpath.
Use some other Maven plugin to perform point 2 e.g. Spring Boot spring-boot:repackage goal.
All the required dependencies, defined in the pom.xml file(s), are downloaded from Maven Central (or others if configured) to the local Maven repository. That repository is located at <user home>/.m2/repository.
Maven generates/calculates a dependency tree to know all the required dependencies for the project. (you can also dump that tree with the command mvn dependency:tree. I always pipe the result to a file, because the tree can be large mvn dependency:tree > deptree.txt). Maven put them all on the classpath when executing a maven command like mvn compile
IntelliJ also use/calculate the dependency tree and add all the jar files to the projects classpath (point to the files in the <user home>/.m2/repository folder). You can see them all in the list with External Libraries, and they will be used / on the classpath for compilation and running the application.
When building a JAR file the dependencies are NOT added to the JAR. Only the bytecode (java classes) and resources from your own project are packaged into the JAR file. (Source files can also be packaged if you configure that)
By adding a Maven plugin (maven-shade-plugin) you can configure your project to also pack dependencies into the JAR. SpringBoot projects also will do that.

What's the difference between Maven Jar Plugin and Maven Source Plugin?

I was reading about how to create a jar file with Maven, but I saw some pom.xml files using Maven Source Plugin and others using Maven Jar Plugin.
In the Apache Maven Project page I found these descriptions:
Apache Maven JAR Plugin
This plugin provides the capability to build jars. If you like to sign jars please use the Maven Jarsigner Plugin.
Apache Maven Source Plugin
The Source Plugin creates a jar archive of the source files of the current project. The jar file is, by default, created in the project's target directory.
Reading these descriptions, I stayed in doubt about when use one or other plugin, and what are the differences or benefits, because I understood that both make the same thing.
The Apache Maven JAR Plugin is used to build jar files containing .class files in order to distribute applications or libraries in bytecode format.
The Apache Maven Source Plugin is used to build jar files containing source files (.java files) in order to allow IDE to show the source code when debugging. This jar file is used in combination with the jar file containing .class files.
maven jar plugin
The jar plugin creates a JAR file from your Maven project. The jar goal of the jar plugin is bound to the package phase of the Maven default lifecycle. When you type mvn clean install, Maven will execute all the phases in the default lifecycle up to and including the install phase, which also includes the package phase.
maven source plugin
The source plugin creates a JAR file with the project source code. It defines five goals: aggregate, jar, test-jar, jar-no-fork, and test-jar-no-fork. All these five goals of the source plugin will run under the package phase of the default lifecycle.
Unlike any of the plugins we discussed before, if you want to execute the source plugin with the Maven default lifecycle, it has to be defined in the project POM file, shown as follows. The super POM file does not define the source plugin; it has to be within your Maven project itself
What is the Difference
Both create JAR files; however, the jar plugin creates a JAR file from the binary artifact, while the source plugin creates a JAR file from the source code. Small-scale open source projects use this approach to distribute the corresponding source code along with the binary artifacts.

How to have tomcat use folder with extension .jar as jar files?

I have in Eclipse web application project that depends from other projects.
When I run debug on embedded Tomcat in lib folder that Eclipse copied not jars, but folders with names like:
dependent_lib1.jar
dependent_lib2.jar
dependent_lib3.jar
....................
So web application don't start because didn't found some files. When I manually deleted all these folders and manually copy jar files - all works.
Does it possible ask Eclipse (or maven - this is maven project) to copy jars or ask Tomcat use folders like jars?
Thanks.
Here is how I think it should be done with maven:
If the other projects are also maven projects, export them as maven artifacts in your local repository. A nice article is Maven Deploy Plugin - If they are not maven projects you should manually generate the jar files and add them to the repository, some information can be found at Best way to create a maven artifact from existing jar
Add the exported artifacts as dependencies to your project. A lot of details can be found at Introduction to the Dependency Mechanism
Hope this helps.
Eclipse cannot do it as its just an IDE, you would need use A BUILD SCRIPT using ANT(Copy tag should do it) and run it before you start your server.
Check this for more details:
http://www.javabeat.net/tips/103-writing-simple-ant-build-script.html

Maven Jar signing and target rearrangement

I'm converting an Ant based project to be buildable by Maven. Standard build is working for now. I'm trying to migrate the additional build targets which are specified in the original Ant build descriptor. Our project can be deployed as a desktop application or as a Web Start launchable client. You can invoke the original Ant file naturally with dist, which simply builds the project but doesn't do post processing for web start, and also there's a dedicated target for JWS which calls dist, then do jar signing and rearranging the distribution files to be be easily deployable to the web server.
I've found out that Maven has a Jarsigner plugin for doing code signing. My project currently builds the core jar, copies all artifact dependencies to target, creates the correct manifest file for the core jar, and also unpacks the configuration artifact to target/ (this contains various things, like XMLs and property files). However i don't know how to fit into the Maven descriptor the following additional steps:
Sign all jar files (also external dependencies), removing existing signatures as well.
Rearrange the resulting jar files to a different directory layout. I also need to edit XML files for this configuration and pack them to a configuration jar which needs to get signed also.
After modification the project have to be buildable the standard way. So Web Start build have to be optional. I should note that we are using NetBeans to build/debug/profile the application.
I'm a little bit lost how to achive these with Maven. Could someone please give some suggestion how should i move forward?
I've solved my problem this way:
I've created a new jar module for the web start client configuration. During build Maven unpacks only those parts of the original config artifact to the build directory which are required for Web Start (you can specify filter rules for the dependency-unpack plugin). Then i'm using the Maven XML plugin to modify XML files using XSLT templates. Finally Maven takes care of packaging all these to a web start client configuration artifact.
I've also created a pom only module for the actual web start client building. This project has no classical artifact output so only the POM gets installed to the artifact repository. This module has dependencies for the source code (excluding original configuration) and for the web start client artifact. I'm using the dependency copying capability of Maven to arrange jar files in the correct structure in target directory. Finally i'm using the Maven jarsigner to sign all jars.

Categories