Appending attributes to manifest.mf of a JAR - java

My application needs me to add some atributes to manifest.mf of different jars without changing the previous version of manifest.mf. In short i want to append some attributes to manifest.mf of JAR. I am using ANT to build my application. In JAVA i can do this while creating the jar with command
jar cfm jar-file manifest-addition input-file(s) given here But i want to do this with an ANT Task.
Is there any ANT task i can use for this? if not then the only solution left with me is
Unzip the jar
Update the MANIFEST.MF
JAR up the content again
This seems to be a lengthy process.
Please suggest.

You could use the <exec> task to run that command line through Ant.

i know you want to add the content of additional files, but maybe you
only need to add simple attributes, this would help
<jar destfile="${web.home}/signapplet.jar"
basedir="${build.home}/applet/signer/classes">
<manifest>
<attribute name="Permissions" value="all-permissions"/>
</manifest>
</jar>

Related

Runnable JAR file export

I have a java project . I want to export it to runnable jar file.
I use eclipse to do it.
But when i run created jar file i receive Error ~ file not found : config\file.xml (the system cannot find the path specified).
How can I export a folder to run success jar file at any where ?
If you don't need your config to be configured outside of jar, just include it in there and access with something like getClass().getClassLoader().getResourceAsStream("config.xml") if it's located at the level of "root" package in jar
Sounds like your application is looking for a configuration file using a relative path in the file system. In order to make the jar totally self-sufficient, the code would have to be modified to look for the config file in the classpath, and the file would have to be included in the jar.
To do this, the code that opens the file must be changed to use Class#getResourceAsStream() instead of using a File object.
I'd suggest you use ant or another build system. Here is a short tutorial on ant:
http://ant.apache.org/manual/tutorial-HelloWorldWithAnt.html
Its pretty easy to create an jar file using xml in your ant build script. I have done it many times:
<target name="jar" depends="compile">
<mkdir dir="${jar.dir}"/>
<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
</jar>
</target>
Others may suggest maven and the like, but in reality they are all good choices. Exporting from an IDE such as eclipse really isn't a viable long term solution.
if you have a config-folder in your projects directory, and there is a file you want to read from, you have to copy this folder to the directory of your jar-file too

Export as runnable jar, but with editable property file?

I have a property file for a client project. I want to export the client as runnable jar, but the properties file should not be integrated into this jar. Because I want of course make edits to it, without having to recompile the jar client file.
How can I export it this way with eclipse?
I'm not currently using Java, but i once used Eclipse to export a runnable JAR. I used the Properties to store the settings and the file was generated automatically in the surrounding folder of the Jar-File. I don't know if this helps you, but it might be a point to start with....
You have to either put them in your project workspace so it is inside the jar (but this is not the case since you do not want that) or load them from a predefined directory, for example you could demand properties file to always be in the same directory as the runnable jar file.
By the way, you don't have to recompile your project if you put your properties file inside a jar. A jar file is just a package, you can unpack it, make edits to your properties file and then pack it again. It will work just as you demand.
If you change your mind, see this post.
If you want the properties file in the same directory as your JAR file, just add an extra step to your Ant build to zip up the properties file and the JAR file.
If not, have your Java code create the properties file where you want it the first time the Java application is run.
It does not seem to be possible to do this using standard Eclipse's export as runnable JAR (right click project -> Export -> Runnable JAR file -> Save as ANT script). However, Eclipse allows you to store the definition of your export as an Ant file, that one can modify later on.
The modification can look like below (I marked the modified parts with comments; it should be easy to compare with a script that your Eclipse generated).
<target name="create_run_jar">
<jar destfile="/mytargetlib/myjar.jar">
<manifest>
<attribute name="Main-Class" value="Main"/>
<!-- Here we only add lib/properties, the rest should be pre-generated by Eclipse -->
<attribute name="Class-Path" value=". lib/myjar1.jar lib/myjar2.jar lib/properties"/>
</manifest>
<fileset dir="/bin" excludes="**/*.properties" />
</jar>
<delete dir="/mytargetdir/lib"/>
<mkdir dir="/mytargetdir/lib"/>
<copy file="myjar.jar" todir="/mytargetdir/lib"/>
<copy file="/myprojectdir/lib/myjar1.jar" todir="/mytargetdir/lib"/>
<copy file="/myprojectdir/lib/myjar2.jar" todir="/mytargetdir/lib"/>
<!-- Again, all the above was generated by Eclipse. We only add a copy of our property file -->
<mkdir dir="/mytargetdir/lib/properties"/>
<copy file="/myprojectdir/properties/mypropertyfile.properties" todir="/mytargetdir/lib/properties"/>
<!-- end of our addition -->
</target>

Adding the current directory to a JAR file's classpath

My code is being deployed as a JAR file. The JAR contains a directory lib which contains a number of third-party JARs which my code requires. I've added these to the classpath, using Ant, via the MANIFEST.MF.
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.0
Created-By: 20.5-b03 (Sun Microsystems Inc.)
Main-Class: com.package.Class
Class-Path: ../lib/c3p0-0.9.1.2.jar ../lib/dbunit-2.4.8.jar ../lib/gua
va-10.0.1.jar ../lib/hsqldb.jar ../lib/javax.jms.jar ../lib/log4j-1.2
.16.jar ../lib/mockito-all-1.9.0.jar ../lib/ojdbc14.jar ../lib/slf4j-
api-1.6.4.jar ../lib/slf4j-log4j12-1.6.4.jar ../lib/xmlunit-1.3.jar
There is also a queries.properties file which is in the root of the JAR.
There are two further properties files which are required. I would like these to reside in the same directory as the JAR file and for the code to be able to locate them. I believe for the code to be able to locate these properties files, they need to be in the classpath. I therefore need to add the JAR file's directory to the classpath.
Firstly, is this the correct approach of should I use an alternative means of locating the properties files?
If this is correct, how do I use Ant to add the JAR's current directory to the classpath in MANIFEST.MF? I added the JARs in the lib directory to the classpath using the manifestclasspath Ant task.
Have you tried adding the . as a reference to the current directory?
<jar jarfile="dummy.jar">
<manifest>
<attribute name="Main-Class" value="com.package.Class"/>
<attribute name="Class-Path" value=". ${jar.class.path}"/>
</manifest>
</jar>
Please also see Executable jar won't find the properties files

making a single-jar java application

If I have a java project that consists of several different types of files (pictures, sound, etc) and multiple jar dependencies, what is a good way to package it all into one single jar that can just be double-clicked?
I know jars by themselves are pretty dumb in that they don't look within themselves for files that they depend on (something I only realized after the slightest bit of frustration (understatement)). -- If jar A depends on classes contained inside jar B, putting jar B inside jar A will not work. Jar A must be in the same directory as jar B.
...Now, I know I could just extract all the files from all the other jars and put everything in the same directory. That would sort of work, but I don't want to do it because: 1. It would be messy and 2. it still wouldn't solve the problem of needing to have the sound files in the same directory as the final jar. (For whatever reason, sound files act the exact same way as internal jars)
Basically, I just want to make it so that the files my application depends on aren't obnoxiously visible and ostentatious. So, if there were some solution where I could put everything inside a jar and have it be the only necessary file to run the entire program, that would be optimal. But, I am willing to accept creative/inventive ways to bypass the problem, such as having a batch script in a parent directory execute the jar or something. (I say "or something" because that exact scenario would only work on windows operating systems. ...you know what I mean!)
Apache Maven plus shade plugin will do exactly what you need.
Check out the "Shade Plugin where a Main-Class is added to the MANIFEST.MF" section here http://maven.apache.org/plugins/maven-shade-plugin/examples.html
You can extract all the JARs and merge them into one common JAR. There are ANT tasks and Maven plugins readily available for doing just this. Additionally, if you're application is properly written, there is nothing preventing you from putting media files and other resources in the JAR as well. You just need to ensure that these resources are "loaded from the classpath", rather than being loaded from the current working directory.
If you use the assembly plugin for maven, you can have it download dependencies, build modules and produce an executable jar.
If you use Maven, then I suggest the shade or assembly plugins.
If not, then read this: Easiest way to merge a release into one JAR file
If you are building an executable jar and have other jars that you need to be available in the classpath, there is a Class-Path: line in the jar's MANIFEST.MF file that lists entries (including jars and directories) to include in the classpath when the main class is run.
I usually use my IDE or ant to build such executable jars and set the Class-Path: header.
By the way, to make your jar executable, set the Main-Class: line in your MANIFEST.MF file.
Here is an example from an executable jar I build:
Main-Class: com.example.app.MyAppCLI
Class-Path: log4j.jar driver.jar libraries.jar
And here is a corresponding ant target to build this:
<target name="exejar">
<jar destfile="myapp.jar"
basedir="bin"
include="**/app/*.class">
<manifest>
<attribute name="Main-Class" value="com.example.app.MyAppCLI"/>
<attribute name="Class-Path" value="log4j.jar driver.jar libraries.jar"/>
</manifest>
</jar>
</target>
If you will use a tool like ant to build your executable jars, it will make the process more easy to repeat, and will also handle strange edge cases for you, like what happens when a header line in MANIFEST.MF gets too long.
If you use Maven, you may a appreciate the onejar-maven-plugin. One major benefit is that all your dependency jars stay in jars, and your code is in its own jar. All of those jars are put in a bigger jar, which is made executable, thus avoiding some potential classpath issues. Read the usage guide and this blog post for more information.
have a java project that consists of several different types of files (pictures, sound, etc) and multiple jar dependencies, what is a good way to package it all into one single jar that can just be double-clicked
A better way to deploy a rich client app. is using Java Web Start. The end user would never see a Jar, and could be provided a desktop short-cut or menu item to launch the app.

How do I attach properties files to a jar?

I have a project that uses the serial port, and it requires two files to run, the win32.dll file (which is in the java runtime environment bin folder) and the javax.comm.properties file (which is in the java runtime environment lib folder). When I run the project from eclipse it works, but when I try to build a jar file for distribution, it won't work. I suspect this is because the dll and properties files aren't included in the jar. How do I specify that they need to be there?
You generally don't put dll and properties files inside the jar. Properties files as well other jar files need to be added to the classpath. The jar file has a manifest file that defines the classpath used. You can't edit this with eclipse. You need to define an ant build.xml file and do something like this:
<jar jarfile="${dist}/MyJar.jar" basedir="${build}">
<manifest>
<attribute name="Main-Class" value="MyClass"/>
<attribute name="Class-Path" value="."/>
</manifest>
</jar>
Then put the properties file in the same folder as the jar. You can run the ant target by right clicking the build.xml and selecting the "Run as Ant target".
If I remember correctly, placing the dll file in the bin directory of the jre will work.
I think javax.comm.properties just need to be on your classpath. You may can add it to the top level of a jar you delivery.
InputStream is = MainClass.class.getResourceAsStream("javax.comm.properties");
if (is == null) {properties missing....}
I think win32.dll just need to be on the %PATH%(windows) or $LD_LIBRARY_PATH(unix)......
A jar file is just a normal zip file. If you want to add files to it, just use a tool such as winzip.
With Ant, you can pack everything in your Jar you want to. So let Ant create your Jar, not Eclipse :)

Categories

Resources