I have a large Java project with a large number of jar file dependencies. When I try to run the project (using exec) from Eclipse or Netbeans, Maven throws an exception which turns out to be a too large number of entries on the classpath (only 2/3 of the needed entries are included). Does anyone know a workaround for this? (Except from building an executable jar and running it from terminal.) Is it possbile to "extend" the "classpath-buffer"-size?
This is a Maven exec plugin bug, it is documented in MEXEC-68, the reporter created a patch so I hope it will be resolved soon.
One workaround would be to add the classpath to the manifest file using this config for the maven-jar-plugin, add the dependencies to a folder and add just that folder to the CLASSPATH envvar.
For example:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
...
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
...
</plugin>
</plugins>
</build>
...
</project>
This will add to the manifest something like:
Class-Path: plexus-utils-1.1.jar commons-lang-2.1.jar
If that JARs are in a CLASSPATH folder, you can run your JAR using maven exec plugin hidding the classpath with something like:
mvn exec:exec [...] -Dexec.classpathScope="test"
I used -Dexec.classpathScope="test" to make the plugin ignore the dependencies and add just the ones in scope test.
This problem is fixed in Netbeans 6.10M1. Please take a look at Bug 188864. If you have an older version, you can still fix this yourself (you just have to edit an xml file inside org-netbeans-modules-maven.jar).
Then, don't forget to check Maven Best Practices (http://wiki.netbeans.org/MavenBestPractices#Binding_Maven_goals_to_IDE_actions) where it is explained how to bind maven goals to IDE actions.
Regards,
Mach
In Java 6 (which I hope you use) you can use wildcards in classpath entries. For the exact syntax check this page Setting the classpath and search to the right section by searching for "Understanding the class path and package names".
Or you try shortening the paths by placing all required jars in a single folder with a short path. e.g. C:\jars\
Related
ive imported a bunch on maven projects from svn and they all (...a lot) try to use
JRE System Library [JavaSE-1.7]
But i only have
jdk1.8.0_102_64Bit
Which i told eclipse about in eclipse.ini with:
-vm C:\Users\myuser\Downloads\jdk1.8.0_102_64Bit\bin
Yet all the imported maven projects insist to use the "System JRE" which is unbound when i check it.
How do you tell maven to use what eclipse knows about? or where does maven get its information about JDK's / JRE'S?
Maven by default uses JAVA_HOME Environment Variable to know which java version to use. Unless you set different one in pom.xml.
Try check every pom.xml of your projects, they must have a plugin section like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<verbose>true</verbose>
<fork>true</fork>
<executable>${JAVA_1_6_HOME}/bin/javac</executable>
</configuration>
</plugin>
Executable tag tell maven to use java 6 in this example.
In this case i probably did something wrong while importing it from svn..a second try worked, but im not sure why :(
I'm currently trying to use Sigar in a maven-build, and it says everytime:
"org.hyperic.sigar.SigarException: no libsigar-x86-linux.so in java.library.path"
I've installed Sigar to maven with mvn install:install-file -DgroupId=org.hyperic -DartifactId=sigar -Dversion=1.6.4 -Dpackaging=jar -Dfile=sigar.jar (where sigar.jar is a jar only with the files in the org-folder, and the maven dependency with the things in the lib-folder), but then it does not find the .so-file.
I've tried to find answers, who mostly say one should unzip the files like Unzip dependency in maven . Unzipping (after installing the other things via install:install-file) does work fine, but the file isn't included in the path after all.
Then I've tried to find something to include the files in the build path, so I did something like this: Surefire JUnit Testing using Native Libraries (I want to use sigar in the tests), but this also doesn't change anything. I've tried it with many different folders, and even adding the file itself and not the folder it is in to the library path, but even this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<forkMode>once</forkMode>
<argLine>-Djava.library.path=${project.build.directory}/lib/libsigar-x86-linux.so</argLine>
</configuration>
</plugin>
does not work, but the file is clearly there. I'm using maven 2.2.1.
Has anybody an hint how to get sigar in this context working?
Thanks in advance,
DaGeRe
Using surefire plugin you do not need to prefix arguments with 'D' prefix (e.g. - -java.library.path=${project.build.directory}/lib/libsigar-x86-linux.so).
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
I am brand new to both java and to maven, so this is likely very simple.
If I follow the maven2 hello world instructions here:
http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html
everything works OK. If I then alter pom.xml to bring in a dependency from a remote repository, the files for this dependency get stored in ~/.m2/repository/new-dependency/.
Using the syntax in the hello world instructions to run the application requires that I add the absolute path to the dependency to my classpath (either by setting the environment variable or via the command line switch):
java -cp target/my-app-1.0-SNAPSHOT.jar:/.../.m2/.../new-dependency.jar com.mycompany.app.App
This will obviously get unwieldy quickly :)
I suspect that this is not the usual way of running a java program and that I just need to read more about .jar files, but while I am doing so I would appreciate any tips on how to do this properly.
I am not using an IDE, btw. vim from the command line.
Thanks!
Mike.
You can use maven itself to run it, I believe it sets the classpath for you.
mvn compile
will compile it
then you run:
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
which will execute it.
You can see http://www.vineetmanohar.com/2009/11/3-ways-to-run-java-main-from-maven/ for some more info on ways to run (including passing command-line args to the thing you want to run)
You can make a jar executable by adding the Main-Class attribute to its manifest file. In Maven this is done by the archiver plugin. To add the Main-Class attribute, add this to your pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.mycompany.app.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
You can now run your jar with the command: java -jar myjar.jar or by double clicking on it (not available in all platforms).
If you want it simple for you and others, then you can generate a jar with all dependencies in it, using the maven-assembly-plugin. Example is here: http://maven.apache.org/plugins/maven-assembly-plugin/usage.html, section Execution: Building an Assembly
You can use the maven-shade-plugin which will create an executable uber war with all dependencies.
OR
Use the appassembler-plugin which creates a script that imports all dependencies and lets you execute a main class from the command line.
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.