How To Re-Jar A Jar File Using Ant
Posted by blogmeister on
October 25, 2013
Well, the truth is, there is no one step way to do this. This is what users tend to do:
- Extract the Jar file
- Delete the Jar file
- Run the Jar command to re-create the Jar file.
So yeah, I can make a batch file for this but since I have no idea how to make one, I decided to use Ant.
Here is my script.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
<?xml version="1.0" encoding="UTF-8"?> <project name="recreate-jar" default="list_jarfiles" basedir="."> <taskdef resource="net/sf/antcontrib/antcontrib.properties"/> <target name="list_jarfiles" description="list jar files in all subfolders"> <foreach target="rejar" param="the_file"> <path> <fileset id="dist.contents" dir="." includes="**/*.jar"/> </path> </foreach> </target> <target name="rejar" description="unsigns signed jar file"> <basename property="the_file.filename" file="${the_file}"/> <dirname property="absolute.path" file="${the_file}"/> <property name="folder_name" value="${absolute.path}_folder"/> <!-- delete folder for extracted jar file if exists before proceeding to recreate folder and extract jar contents. the folder name should be like JARNAME_folder --> <if> <available file="${folder_name}" type="dir" /> <then> <delete includeemptydirs="true"> <fileset dir="${folder_name}" includes="**/**"/> </delete> </then> </if> <mkdir dir="${folder_name}" /> <!-- extract all jar file contents to folder --> <unzip src="${the_file}" dest="${folder_name}"/> <!-- delete jar file --> <delete file="${the_file}" /> <!-- create jar file using custom manifest. make sure you change the path if ever the folder is different in your workstation. --> <jar destfile="${the_file}" duplicate="preserve" manifest="manifest.mf" basedir="${folder_name}" excludes="META-INF/**" includes="**" > </jar> <!-- after creating jar, delete folder of extracted files --> <delete includeemptydirs="true"> <fileset dir="${folder_name}" includes="**/**"/> </delete> </target> </project> |
The following explains the steps that the build script executes:
- Go over all folders recursively to look for existing jar files.
- Extracts them one by one in a folder name that is the name of the Jar file + “_folder”.
- Delete the old Jar file
- Re-create the Jar file
- Delete the folder
That’s it! Simply put the build script file in any folder you want it to start searching for Jar files and it does the rest.
How To Fix Invalid SHA1 Signature When Signing JAR Files
Posted by blogmeister on
October 11, 2013
You most likely happened to re-sign an existing signed jar that just expired recently and got this error message saying invalid SHA1 signature.
There is only 1 cause for this and you happen to re-sign the jar using JDK 1.7 while the expired jar was signed using 1.6. The encryption for both JDKs are different because 1.6 uses SHA1 while 1.7 uses SHA-256.
When you re-sign the expired jar using 1.7, check the manifest file and you will see that there will be 2 entries labeled SHA1 and SHA-256.
The only workaround that can be done for this is to re-create a clean jar file and sign it using 1.7. However, in my case wherein there were too many jar files I decided to install 1.6 and use its jarsigner executable to re-sign it thereby keeping its signature intact as SHA1.
You can then verify your jar file with the command
jarsigner -verify -verbose -certs
just to be sure that the signing was successful. Do not worry if you see the message “This jar contains entries whose signer certificate has expired.” because this is normal as it simply means you overwrote an expired certificate with a new one.
How To Implement A Single Instance Java Web Start Or Applet
Posted by blogmeister on
August 6, 2013
I think it started with Java 1.6 that a JNLP jar file was included that can let you run a Java web start application or applet in a single instance.
Through the SingleInstanceService class, you application or applet will be able to detect if another instance is run when it is called from a JNLP.
I have not tried this with an applet that is run from an <APPLET> tag but I tested this in an applet if it is called from a JNLP.
Simply implement SingleInstanceListener from your class and initialize it with this code:
|
1 2 3 4 5 6 |
try { SingleInstanceService singleInstanceService = (SingleInstanceService) ServiceManager.lookup("javax.jnlp.SingleInstanceService"); singleInstanceService.addSingleInstanceListener((SingleInstanceListener) this); } catch(UnavailableServiceException use) { Logger.getLogger(JViewerAsFrame.class.getName()).log(Level.SEVERE, null, use); } |
And in the newActivation() method, you can put in a message prompt that looks something like this:
|
1 2 3 4 |
@Override public void newActivation(String[] strings) { JOptionPane.showMessageDialog(this, "Only one instance is allowed.", "Error", JOptionPane.ERROR_MESSAGE); } |
Easy, right?
By the way, if this code is run within an IDE, it will return an exception. This will have to be run from a JNLP in order for it to work.









