java library inside jar - java

I have created mytest.jar file with library that contains near 30 library files also jar.
Is it possible to put all library jars inside mytest.jar so that I need to distribute only 1 jar?
May be it can be done using manifest?
Thanks.

Loading classes from jars-inside-jars is not possible with the standard Java classloader. However it is possible using a custom classloader, this is how for example UberJar works.
The maven shade plugin takes a different approach. It will unpack all the jars you depend on, and pack them (along with your own classes) into one big jar. Then the normal classloader can be used. This is simpler, and is also possible without maven using jarjar.

Not out of the box. However, One-Jar provides a solution. It works fine for standalone apps, which is what I assume you' re making.
If you're making an applet instead, One-Jar won't work.

Usually one uses a jar repacking tool like jarjar for this purpose.

Related

Reusing Z3 as a library jar in Java

Currently I am working on a tool for my masterthesis which uses Z3. I have chosen to use the Java bindings within my Scala project. Now I would like to create a distributable jar which may be used both standalone and by other projects. Unfortunately, I have not been able to find a simple way to do it as the com.microsoft.z3.jar uses native libraries such as libz3.{so,dylib,lib,dll}.
Normally, native libraries have to be linked by adding the -Djava.library.path=... flag specifying where the native libraries may be found.
I have been looking at SBT pack, assembly and one-jar but none of these packaging tools seem to allow reuse by other projects and link the native libraries automatically; also when my project is used as a library.
Ideally, the result is a .jar where the native libraries are included and Java knows where to find them (java.library.path) without the user having the specify anything. The .jar itself may be executed or imported as a library by another project.
Would I have to fallback to a situation where the flag -Djava.library.path=... has to be included for each project using Z3?
Any suggestions are more than welcome! Thanks!

Standard location to put jar files for command line java programs

Several developers have created stand alone java command line programs. These programs share libraries, such as sql server jar. What is the preferred or standard location these shared external jar files be placed according to convention?
/usr/local/lib
/opt
/var/lib
The location doesn't matter as much as standardizing the location. Another solution would be to use a dependency management system like Maven and package the dependencies in the jar. However, this would be inefficient if you are reusing the jars across multiple projects but it does ensure that the dependencies are present and isn't susceptible to someone swapping the version of the dependency in the shared folder with a newer version that breaks other applications.
Java provides several ways to manage class and library loading, but looking for one location based on the OS is not something that is in line with keeping Java platform independent. Instead try defining a common location for your project based on how Java finds classes.
Also, if you are executing your command line app from jars, Maven has some nice plugins to help bundle your java classes as an executable jar. It is much cleaner and encapsulates the libraries within the scope of your individual applications.

Difference between a jar file and a library in Java

NetBeans allows the programmer to add a library and a jar file.
What is the difference between a jar file and a library? Is library similar to GAC assembly as in Windows.
There are similar questions, but they are way too specific and I was not able to understand the difference.
to put things very simple : library is a collection of jars
You could like create a global library java-ee which contains all Java EE related jar files. Then you could use this global library in your different projects. It will be simpler to manage them; and adding in new projects.
A JAR serves the same function an an Assembly in the C#/.net world. It's a collection of java classes, a manifest, and optionally other resources, such as properties files.
A library is a more abstract concept, in java, a library is usually packaged as a JAR (Java ARchive), or a collection of JARs.
A jar file is zip archive containing among other files, the java class files. A Netbeans library contains resources required by the project, including jar files.
If well understood: A library is simply a folder that groups classes. For example in JDK, a library present there is a group of classes stored together.
If not mistaken a .jar file is a group of compiled classes in .class format and was created by Java creators so a program will be OS independent; which means within a JVM you will run your app in .jar format on a Linux, Windows, etc without re-coding tour app for various OSs.
This article explains it all..
It states
Java's libraries are commonly known as class libraries. However, Java
refers to class libraries as packages.

How do I build a single bundled JAR with all the needed classes to run a Java application?

I'm going to deploy a Java application with a custom launcher, and I need to have all the classes needed for my app in a single jar file so I don't have to deploy the entire Java SE libraries with it.
I was thinking of using some pre-existent ant tasks to create a target that recursively searches all my compiled classes files for its dependencies. After all the dependencies have been determined it would extract the needed class files from their JAR's, copy it along with my classes to an output directory and make a single jar from it.
If there's no such thing avaliable out of box, I can create one myself, but I need to know how references to other classes are stored in .class files. It could be much easier if there's some kind of java library like .NET's Mono.Cecil/System.Reflection that exposes an high level API for inspecting/manipulating Java.
Since I'm new to Java, I'm having some trouble in finding what is needed to acomplish those things. Can someone give me some direction?
Unfortunately, you cannot ship only part of Java SE - that will breach the license agreement. If you use Java SE, then all of Java SE must be available.
The simplest way to achieve this is to use an Ahead Of Time compiler. These take care of packaging only the classes you need, and adhere to the JDK license agreement by making the "unused" parts of the JDK available via optional download.
For example, Excelsior JET is a good AOT compiler and will package just the classes you need. It's not free for commercial use, although open source projects can apply for a free license grant.
Alternatively, you may simply assume that the user has the JRE already since it's installed on over 90% of desktops, and in cases where the JRE is not available, have your installer download one for the user. AdvancedInstaller has a free edition that will accomplish this.
After all the dependencies have been
determined it would extract the needed
class files from their JAR's, copy it
along with my classes to an output
directory and make a single jar from
it.
As an easy solution, if you use Eclipse IDE you use the following solution:
Under the Java project properties (right click):
Export... => Export as Runnable JAR
The exported JAR will have all its dependencies packed into it.
alt text http://www.ubuntu-pics.de/bild/97131/selection_016_mg6IDm.png
Here is one suggestion I found on the web:
<jar destfile="${build-abc}/abc.jar" duplicate="fail" index="true">
<zipfileset src="${compile-lib}/demo.jar" includes="**/*.class"/>
</jar>
This should add the dependencies to the jar (as shown with demo.jar). You still have to adapt the manifest file so that the added jars appear on the classpath.
This doesn't solve the 'Java SE' classes problem - you'll have to bundle a jre in the installer package or depend on an existing one on the target system.
You won't have to deply Java SE classes, as they already are in the customer JRE.
If your dependencies are expressed ion a common way (through Maven or Ivy) i guess it's quite easy to find an equivalent of maven uberjar task ... which will do what you want to do, but in a more simple way (as it simply repacks all jars in one big jar).

How to combine library with my jar?

Ok so i wrote a program that makes use of a 3rd party open source library and i want to package it with my program in a single jar. I'm using netbeans 6.8 and everything I've tried java always spit back the error:
java.lang.NoClassDefFoundError: libraryname;
off topic:also i would like to know how to make an executable-jar(exe) through netbeans if it is possible. (ive seen programs that were written in java but were an .exe)
EDIT discovered a plugin for eclipse called FatJar which can do what i want, but i cant find something similar for netbeans, is there such thing?
I'll start off with the obligatory disclaimer: Java executable JARs do not work this way. An executable JAR has a main class defined in the JAR's MANIFEST.MF file, and the MANIFEST also allows the definition of a class path to include libraries that the code in the executable JAR will need. The class path definition in the MANIFEST must enumerate every JAR or folder to put on the class path, relative paths are relative to the location of the executable JAR - not to paths contained inside the executable JAR. Executable JARs are launched with the "-jar" argument to the java executable, and both the java "-cp" flag and the CLASSPATH environment variable are ignored. As for why executable JARs were designed this way, you should be aware of the primary disadvantage of loading classes from JARs contained within JARs, even though the rest of this reply will focus on doing just that.
NOTE: I lost the original sun forum topic that explained it fully, but essentially it is because entries in the top level JAR can be read in a random access manner, but the entire embedded JAR must be read before any entries can be accessed, because the top level JAR might have compressed its entries.
I have used One-Jar successfully in the past, but the structure of the final resulting jar may not be what you expect. Essentially the One-Jar classes are the only non-JARd classes in the final jar; all other code (your code and any dependent library code) is included in the resulting as JAR as JAR files. Your application is JARed as a regular JAR file named "main.jar" in the final JAR's "main" folder. Any libraries your code needs is placed, as JAR files, in the final JAR's "lib" folder. And last but not least the final JAR's MANIFEST.MF file tells One-Jar what your main class is. Execution is a dead simple "java -jar final.jar [args your app uses]". I don't know how to take the next step of converting to an OS-native EXE regarding your off-topic question, but it would probably be best to use a different packaging mechanism than One-Jar anyway. I'm not sure how to go about this with NetBeans, my advice there is to use a build tool to package the final jar. Fortunately One-Jar provides instructions on generating the final jar with Ant, and that should be easily integratable into NetBeans.
I believe the Eclipse FatJar plugin creates a One-Jar executable JAR, so if that plugin seems to do what you want, then One-Jar is the way to do it. Personally, I used a Maven assembly.
There is a caveat - any signed libraries that require (or desire) to take advantage of Java's signed JAR verification may not work this way - Java Cryptographic Extension (JCE) implementations like BouncyCastle are a notable example. I think the reason is that the signature verification runs against the final JAR, not the signed library. Fortunately One-Jar allows the end user to add additional libraries to the classpath, something that is explicitly precluded when running an executable JAR; to workaround this you might be better off delivering the problematic JARs with the final JAR and an OS dependent launch script (.bat, .sh, etc).
I realize that this doesn't achieve exactly what you want, but I'll describe the customary method of distributing a standalone application. If it does meet your needs, you'll find that it's better supported by tools and more readily understood by users, because it follows established conventions.
Put your code in a jar (I'll call it app.jar) along with a META-INF/MANIFEST.MF file with entries like this:
Main-Class: com.y.app.AppMain
Class-path: third-party.jar blort.jar foo.jar
Then, you can throw all of the jars into a directory and run AppMain like this:
java -jar app.jar
If you want, you can put the third-party libraries in a single directory like lib and refer to them in the Class-path attribute using a path relative to the main jar: lib/third-party.jar That helps keep your distribution tidy.
My generic answer to your off-topic question is a (rather lengthy) article: Convert Java to EXE - Why, When, When Not and How. It has lots of links to free and commercial tools, but I have never seen a Netbeans plugin with such functionality, sorry.
To include another jar in your jar, you might find jarjar useful.
Executable jars just have a class defined as 'Main', if I'm not mistaken. This may be useful.
If there's not any concern of repackaging 3rd party jars into your final big jar, then this should be the easiest method.
If there are no licencing issues then the most preffered way is to unjar the actual jar and rejar it with your class files in it, to a new jar.
You can simply use the jar cmd itself for this, no big deal!!
if you use MAVEN, use "maven-shade-plugin" plugin. It will compile jar with all dependencies(3rd party and etc.)

Categories

Resources