Recursively including jars into the classpath - java

I have a project with several third-party JAR files in several directories. Currently, the project uses some ant tricks to recursively include all jar files into the classpath. I want to build a deployment for another site which will include JAR'ing my own code into a single file and somehow including the other JARs that I need. Oracle claims that wildcards on the commandline will not recursively include jars. I want the deployment to work in Windows or Linux.
It seems like I have the following options:
Include ant with my JAR and run the existing script.
Somehow re-organize the jars to be in a single directory so I can use a wildcard in my classpath. Hopefully it won't break the third-party libraries.
Manually create a big, ugly classpath.
Does anyone know of an easier way? I'm inclined to go with #1 for now.

I'd go with #2. When you build your distribution, copy all the jars to a "lib" directory, then include them all using wildcards. I've never known a third party library to break when doing such a thing.
There shouldn't be much trickery to it using ant: use copy with flatten="true" and include the fileset(s) indicating the directories/jars to recurse through.

option 4: The goal is to make you app startable simply with
java -jar your.jar
The main class and the classpath are set in the MANIFEST.MF of your.jar. Use ant to create the classpath at build time. This can be either a big, ugly, nested tree or a big, ugly flattened tree in lib.
See here, here and here for examples.

You can use JarJar and put everything in a single JAR file. You'll need to verify third-party licensing and distribution terms to ensure you can repackage their libraries.

Related

Gradle: Create a non-executable jar and executable shell script with dependent libraries as a package distribution

I am not a big fan of creating fat executable jars for java programs as it involves a massive overhead when I have multiple executable programs from the same project.
I want to be able to create a single library-like jar and create corresponding .sh scripts which pretty much have the structure of:
java -cp classpath_libs main_class program_args...
or any other executable where I can customize it to my needs but in a similar fashion(ex: hadoop jar project_jar main_class classpath_libs program_args). Is this achievable in gradle? if so, how? Note, I need to create multiple scripts using different main classes from a single project.
Key requirement here is to be able to use final fully resolved classpath string.
UPDATE: I have seen examples of using the application plugin but it creates an executable jar with dependent libraries packaged into it. This is NOT what I am looking for.
So far as I have found, it appears there's no plugin that handles this directly. So, I used the java-library plugin, used the configurations.runtime classpath value and created the necessary scripts and the copy task to copy the libraries necessary into the necessary directories. For anyone interested, you may also try the distZip option in application plugin where gradle does create scripts for execution and package the necessary libraries in a distribution. You can take a look at the output of the script to see how the classpath is structured and create something similar.

Maven Project with the need of several local libraries

I have read numerous posts regarding this, and I was still not able to find a clear-cut answer.
We have the need to use a proprietary SDK in our maven project and this SDK contains ~315 jar files that are needed for around 30 lines of code (SAP product). Every answer I read dealt with adding individual jars to your local maven repo. That is fine and I understand that, but is it possible to add an entire directory of libraries. These libraries are only needed for compiling the project since they are already on the classpath of the target server (They would all be scoped as provided in a pom).
I've tagged Netbeans 8 since that is the IDE I am using, so if anyone knows a hack to get a maven project in netbeans compiled using libraries on Netbeans classpath that would be a good solution as well...
JAR's are just java .class organized in folders and Zipped. Extract all those 315 JARs to somewhere, thus merging all of their content, and then Zip it again to one single fat JAR file. Add this fat JAR to your local repository as you have read elsewhere.
This other question can help you with the JAR merging thing: How to combine two Jar files
Although there are many messy workarounds for this, the ideal would be to let the compilation fail and search for the missing compile jars using a search utility like agent ransack you can search within the jars in that directory for the missing classes referenced in the compiler errors. As you find the jars you need, add them as dependencies with the scope of provided.
A less clean option would be to zip all of the jars, use the dependency plugin to unpack them to a folder and add that folder to the classpath of the build, then remove them or exclude them from the final package.

Eclipse doesn't see CLASSPATH

I have some JAR files on my CLASSPATH environment variable. When I open cmd and enter echo %CLASSPATH%, the paths to those JARs are part of the output. When I try to compile and run a java class through cmd that imports classes from these JARs, it works, and I don't have to add the JARs with -cp.
But when I try to import these classes in Eclipse, it doesn't work. The import cannot be resolved. I have to add them to the build path.
This means that when I get a new version of a library, I have to add it to the build path, and remove the old version, for each project that uses the library. I also have to recompile the projects that I have runnable JARs of, because each uses its own separate copy of the library (which, by the way, just seems wasteful and unnecessary). If it worked as I intended, I'd only have to change the version number in CLASSPATH.
Is it possible to make it work like I intended? Or is there a better way to handle JARs and JAR updates?
You can define a User Library in the preferences and refer to that in your projects' Java Build Paths, changing the JAR files it contains as needed. For updating your runnable jars automatically, that might well be better suited to a system such as Ant or Maven. As for having redundant copies in your Runnable JARs, that's just part of what makes them "runnable."

Compiling with .jars results in missing .class files

When writing my projects, I use a number of apis and libraries. The projects compile - I have added the .jars to my classpath - however, the relevant .class files are not added to the final jar. Is there a way to force this? I'm not using an IDE like Eclipse (and would honestly prefer not to).
No, the classes aren't meant to be added to your jar file. Instead, the idea is that you supply the 3rd party jar files alongside your own jar file. If you really need to only have one jar file, you'd need to merge all the jar files together - but I'd strongly recommend that you don't do this unless it's absolutely vital. (You'll need to work out how to merge the manifests etc).

Can i combine many jar files in one jar file

I have multiple JAR files, which I have to add to classpath in Eclipse.
Is it possible to combine 30 files in one file and include that file?
You can, but I don't think it would necessarily be a good idea to do so. Three possible reasons, and no doubt there are more:
It makes it harder to see where any one constituent file comes from.
It makes it harder to replace just one library
If there are files which are contained in multiple jar files, which should "win"? For example, all the jar files will have their own manifest... you may be able to merge them all, but not necessarily... and for other files there may well simply not be a sensible way of merging them.
My vote is to keep the jar files separate.
Your may want to have a look at jarjar.
If you use an ant task you can also go for zipgroupfileset:
<zip destfile="jarlibrary.jar">
<zipgroupfileset dir="lib" includes="*.jar"/>
</zip>
There are a number of existing tools for this:
Uberjar
Megajar
Onejar
This question seems probable duplicate. Please try to find answer from similar article in this forum
Clean way to combine multiple jars
The jarjar project is what you need.
There is another thread here that explains how to package jars for releases, including using Ant, jarjar and eclipse plugins.
First, you can. JAR is just a ZIP file. You can extract all stuff into one directory, then create zip file (even manually using WinZip or similar tool), call the result *.jar (if you wish) and add it into the classpath.
The only problem that will probably happen is if several jar files contain resources with the same name (and path). for example, manfest.mf, or other descriptors. In most cases it will not cause any problem but sometimes if application code uses these resources you can have trouble.
There are some automatic tools that do this. Take a look on JarJar.
BUT the more important question: why do you want to do this? If you do not use maven put all library jars to one directory named lib under your project. Then add all these jars to your classpath in eclipse using 2-3 clicks. That's it.
if you are using maven, include all your direct dependences into your pom.xml, compile the project, then say mvn eclipse:eclipse. This will create .classspath and .project for you. Now just use it.
Jar files are just ZIP files, so you can try to unzip all jars, put all files together and then ZIP them again.

Categories