How to copy a signed jar file?

I have a jar file that is singed. I only need to update a text file inside this .jar file every few minutes by replacing it with another file from outside (same name but different size and contents). So I'm just copying the files from the old jar to a newly created one, then delete the old one and rename the new jar file to the name of the old one. It works fine when it's not signed - I don't get any errors. But when I'm trying to do this over a signed .jar - the Java VM throws a security exception bound to the file that has been 'replaced' (complaining that the "SHA1" (checksum) didn't pass on the replaced file.). If someone knows if there's a way to bypass/sign it programmatically please let me know

Here's my code:

......

File theJar =new File( sFilePath );

File jarFileDir =new File( theJar.getParent() );

String sFileName = theJar.getName();

String sNewFileName ="new_file.jar";

String sNewFilePath = jarFileDir.getPath() + Log.slash + sNewFileName;

try{

JarInputStream jarIn =new JarInputStream(new FileInputStream( theJar ) );

Manifest manifest = jarIn.getManifest();

JarOutputStream jarOut =new JarOutputStream (new FileOutputStream ( sNewFilePath ), manifest );

byte[] bytes =newbyte [ 4096 ] ;

JarEntry entry =null;

while( ( entry = jarIn.getNextJarEntry() ) !=null ){

String sEntryName = entry.getName();

boolean isDatabase = sEntryName.indexOf( sDatabaseName ) > -1;

if( isDatabase ){

continue;

}else{

jarOut.putNextEntry( entry );

}

int iRead = 0;

while( (iRead = jarIn.read( bytes )) != -1 ){

jarOut.write ( bytes, 0, iRead );

}

jarOut.closeEntry();

}

JarEntry dbEntry =new JarEntry( sDatabaseName );

File dbFile =new File( jarFileDir.getPath() + Log.slash + sDatabaseName );

bytes = Log.getFileInBytes( dbFile.getPath() );

jarOut.putNextEntry( dbEntry );

jarOut.write( bytes, 0, bytes.length );

jarOut.closeEntry();

jarOut.flush();

jarOut.close();

File f1 =new File( sFilePath );

f1.delete();

File f2 =new File( sNewFilePath );

f2.renameTo( f1 );

dbFile.delete();

}catch( Exception exc ){

exc.printStackTrace();

}

[3468 byte] By [xlinuksa] at [2007-11-27 6:16:41]
# 1
Why not put it outside of the jar? Or, into another jar?Signing is used to protect the integrity of the jar file and it shouldn't be changed too often.
wangwja at 2007-7-12 17:28:37 > top of Java-index,Security,Signed Applets...
# 2

The file _was_ outside the jar file in the past versions of the app. But later, I found that keeping the database.txt file (the file to update) inside the .jar file actually makes the application monolithic and much easier to mantain, not to mention other good reasons that would be hard to explain on the forum. In other words - I need it a lot. Please help.

I thought it's a matter of the certificate's "finger prints" that are lost along copying the file that's being updated, and I found the "JarEntry.getCertificates()" method - but I have no clue whether/how it can be used to save the situation.

xlinuksa at 2007-7-12 17:28:37 > top of Java-index,Security,Signed Applets...
# 3

I don't know a standard way to re-sign the database.txt file unless you call the jarsigner tool.

If you're only using the jar like your posted code does, you can catch the Exception when reading download.txt. If your jar file itself is used to contain your executable code, the JRE may automatically check the signatures and there's no (at least no easy) way to alter that process.

wangwja at 2007-7-12 17:28:37 > top of Java-index,Security,Signed Applets...
# 4

I had an idea to use the FileChannel class to programmatically create "free space" inside the .jar file (at the end of it) that would probably not be checked by the JRE cause it would be just bytes - not a file to check it, or other ways like including a shallow image where I could actually write bytes to some location of it. But after some playing around I gave up because there seem to be too many bugs in java.nio like this one

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6526860

this bug has been scheduled to be closed by JDK7, which might then be rescheduled to JDK8 as it sometimes happens.

Hopefully the OpenJDK project or the Apache Harmony project will be more quick at fixing such bugs. With this showstopper I'm going back to my old code of keeping track of another file and locking it as a way to keep away users from editing it manually.

xlinuksa at 2007-7-12 17:28:37 > top of Java-index,Security,Signed Applets...