Je ne sais pas pour l'outil mais j'ai fais une classe permettant de modifier un JAR voici le source:
//import java.io.*;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
//import java.util.*;
import java.util.Enumeration;
//import java.util.zip.*;
import java.util.zip.Deflater;
//import java.util.jar.*;
import java.util.jar.JarFile;
import java.util.jar.JarEntry;
import java.util.jar.Manifest;
import java.util.jar.Attributes;
import java.util.jar.Attributes.Name;
import java.util.jar.JarException;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
public class JarModifier extends OutputStream
{
private final static int BUFFER_SIZE= 10240;
private static byte[] sBuffer= new byte[BUFFER_SIZE];
private static Attributes sStandardAttributes= initStandardAttributes();
private static Attributes initStandardAttributes()
{
Attributes lRes= new Attributes();
lRes.put(Attributes.Name.SEALED, "true");
return lRes;
}
private static void streamTransfer(InputStream aIn, OutputStream aOut) throws IOException
{
int lLen;
while( (lLen= aIn.read(sBuffer, 0, BUFFER_SIZE)) > 0 )
aOut.write(sBuffer, 0, lLen);
}
private boolean mIsFlushed= true;
private boolean mAddEntriesFlag= false;
private boolean mMakeTransferFlag= false;
private File mJarFile= null;
private File mTmpFile= null;
private JarInputStream mJarStream= null;
private Manifest mManifest= null;
private JarOutputStream mOutputStream= null;
private JarOutputStream mActiveOutputStream= null;
private JarEntry transfertOtherEntries(String aEntryName) throws IOException
{
JarEntry lRes= null;
if( mMakeTransferFlag )
{
mTmpFile= File.createTempFile(".jar_", ".swp", null);
mTmpFile.deleteOnExit();
mOutputStream= new JarOutputStream(new FileOutputStream(mTmpFile), mManifest);
boolean lFlag= true;
int lCnt= 0;
JarEntry lEntry;
mOutputStream.setMethod(JarOutputStream.DEFLATED);
mOutputStream.setLevel(Deflater.BEST_COMPRESSION);
while( (lEntry= mJarStream.getNextJarEntry()) != null )
{
String lEntryName= lEntry.getName();
if( lFlag && (((aEntryName != null) && lEntryName.equals(aEntryName)) || lEntryName.equals(JarFile.MANIFEST_NAME)) )
{
if( lEntryName.equals(aEntryName) )
lRes= lEntry; lFlag(lCnt++) 0;
}
else
{
JarEntry lNewEntry= new JarEntry(lEntryName);
try
{
lNewEntry.getAttributes().putAll(lEntry.getAttributes());
}
catch(NullPointerException ex)
{
}
mOutputStream.putNextEntry(lNewEntry);
streamTransfer(mJarStream, mOutputStream);
mJarStream.closeEntry();
mOutputStream.closeEntry();
}
}
mMakeTransferFlag= false;
}
return lRes;
}
private void openStream() throws IOException
{
if( mJarStream != null )
throw new JarException("L'archive est d‚j… ouverte");
JarInputStream lRes= null;
try
{
lRes= new JarInputStream(new FileInputStream(mJarFile));
mManifest= new Manifest(lRes.getManifest());
mIsFlushed= false;
mMakeTransferFlag= true;
}
catch(NullPointerException eEx)
{
throw new JarException("Tentative d'ouverture d'un fichier inexistant");
}
mJarStream= lRes;
}
public JarModifier(String aFilename) throws IOException
{
FileNotFoundException lFileNotFoundException= new FileNotFoundException("Le fichier '" + aFilename + "' n'existe pas");
FileNotFoundException lNotAFileException= new FileNotFoundException("'" + aFilename + "' n'est pas un fichier");
try
{
try
{
if( aFilename.length() == 0 )
throw lFileNotFoundException;
}
catch(NullPointerException eEx)
{
throw lFileNotFoundException;
}
File lAux= new File(aFilename);
if( !lAux.exists() )
throw lFileNotFoundException;
if( !lAux.isFile() )
throw lNotAFileException;
mJarFile= lAux;
}
catch(IOException eEx)
{
throw (IOException)eEx.fillInStackTrace();
}
}
public boolean entryExists(String aEntryName) throws IOException
{
JarFile lJar= null;
try
{
lJar= new JarFile(mJarFile);
return lJar.getJarEntry(aEntryName) != null;
}
catch(NullPointerException eEx)
{
throw new JarException("Tentative d'ouverture d'un fichier inexistant");
}
finally
{
try
{
lJar.close();
}
catch(NullPointerException eEx)
{
}
}
}
public void deleteEntry(String aEntryName) throws IOException
{
openStream();
try
{ if( (mManifest.getEntries().remove(aEntryName) null) || (transfertOtherEntries(aEntryName) null) )
{
mIsFlushed= false;
throw new JarException("L'entr‚e '" + aEntryName + "' n'existe pas dans cette archive");
}
}
finally
{
transfertOtherEntries(aEntryName);
close();
}
}
public void openEntry(String aEntryName) throws IOException
{
openStream();
JarEntry lOldEntry= transfertOtherEntries(aEntryName);
JarEntry lNewEntry= new JarEntry(aEntryName);
try
{
lNewEntry.getAttributes().putAll(lOldEntry.getAttributes());
}
catch(NullPointerException eEx)
{
}
mOutputStream.putNextEntry(lNewEntry);
mActiveOutputStream= mOutputStream;
}
public void addEntries() throws IOException
{
openStream();
mAddEntriesFlag= true;
transfertOtherEntries(null);
}
public void addEntry(String aEntryName, Attributes aAttributes) throws IOException
{
mActiveOutputStream= null;
if( !mAddEntriesFlag )
throw new JarException("L'archive n'est ouverte pour cr‚er de nouvelles entr‚es");
if( entryExists(aEntryName) )
new JarException("L'archive contient d‚j… l'entr‚e '" + aEntryName + "'");
mManifest.getEntries().put(aEntryName, aAttributes);
JarEntry lNewEntry= new JarEntry(aEntryName);
try
{
lNewEntry.getAttributes().putAll(aAttributes);
}
catch(NullPointerException eEx)
{
}
mOutputStream.putNextEntry(lNewEntry);
mActiveOutputStream= mOutputStream;
}
public void addEntry(String aEntryName) throws IOException
{
addEntry(aEntryName, sStandardAttributes);
}
public void write(int aByte) throws IOException
{
try
{
mActiveOutputStream.write(aByte);
mIsFlushed= false;
}
catch(NullPointerException eEx)
{
throw new JarException("L'archive n'est pas ouverte");
}
}
public void write(byte[] aBytes) throws IOException
{
try
{
mActiveOutputStream.write(aBytes);
mIsFlushed= false;
}
catch(NullPointerException eEx)
{
throw new JarException("L'archive n'est pas ouverte");
}
}
public void write(byte[] aBytes, int aOffset, int aLength) throws IOException
{
try
{
mActiveOutputStream.write(aBytes, aOffset, aLength);
mIsFlushed= false;
}
catch(NullPointerException eEx)
{
throw new JarException("L'archive n'est pas ouverte");
}
}
public void flush() throws IOException
{
try
{
if( !mIsFlushed )
{
mOutputStream.flush();
mIsFlushed= true;
}
}
catch(NullPointerException eEx)
{
throw new JarException("L'archive n'est pas ouverte");
}
}
public void close() throws IOException
{
if( mJarStream != null )
{
flush();
mActiveOutputStream= null;
try
{
mOutputStream.close();
mOutputStream= null;
}
catch(NullPointerException eEx)
{
}
mJarStream.close();
mJarStream= null;
if( mIsFlushed )
{
String lFilename= mJarFile.getPath();
mJarFile.delete();
FileOutputStream lOut= new FileOutputStream(lFilename);
FileInputStream lIn= new FileInputStream(mTmpFile);
streamTransfer(lIn, lOut);
lIn.close();
lOut.close();
mTmpFile.delete();
mJarFile= new File(lFilename);
}
mTmpFile= null;
mIsFlushed= true;
if( mAddEntriesFlag )
{
mAddEntriesFlag= false;
mJarStream= new JarInputStream(new FileInputStream(mJarFile));
mIsFlushed= false;
mMakeTransferFlag= true;
transfertOtherEntries(null);
close();
}
mManifest= null;
}
else
throw new JarException("L'archive n'est pas ouverte");
}
public void finalize()
{
try
{
close();
}
catch(IOException eEx)
{
eEx.printStackTrace();
}
}
}
Et un exemple d'utilisation:
import java.io.PrintStream;
import java.net.JarURLConnection;
class ModifJar
{
public ModifJar()
{
try
{
String lFilename= ((JarURLConnection)getClass().getResource("ModifJar.class").openConnection()).getJarFile().getName();
JarModifier lJar= new JarModifier(lFilename);
lJar.deleteEntry("tutu.txt");
lJar.openEntry("titi.txt");
PrintStream lOut= new PrintStream(lJar);
lOut.println("Coucou n°2 !!");
lOut.println("C'est super !!!!!");
lOut.close();
lJar.addEntries();
lJar.addEntry("tuture");
lOut= new PrintStream(lJar);
lOut.println("Nouveau !!");
lOut.println("Création .");
lOut.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] aArgs)
{
new ModifJar();
}
}
Core Breaker :)