Comment créer un fichier JAR par programme en utilisant Java.util.jar.JarOutputStream
? Le fichier JAR produit par mon programme semble correct (il extrait très bien) mais lorsque j'essaie de charger une bibliothèque à partir de celui-ci Java se plaint qu'il ne peut pas trouver les fichiers qui sont clairement stockés à l'intérieur. Si j'extrait le Fichier JAR et utilisez l'outil de ligne de commande jar
de Sun pour le recompresser, la bibliothèque résultante fonctionne très bien. En bref, quelque chose ne va pas avec mon fichier JAR.
Veuillez expliquer comment créer un fichier JAR par programme, avec un fichier manifeste.
Il s'avère que JarOutputStream
a trois bizarreries non documentées:
Voici la bonne façon de créer un fichier Jar:
public void run() throws IOException
{
Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
JarOutputStream target = new JarOutputStream(new FileOutputStream("output.jar"), manifest);
add(new File("inputDirectory"), target);
target.close();
}
private void add(File source, JarOutputStream target) throws IOException
{
BufferedInputStream in = null;
try
{
if (source.isDirectory())
{
String name = source.getPath().replace("\\", "/");
if (!name.isEmpty())
{
if (!name.endsWith("/"))
name += "/";
JarEntry entry = new JarEntry(name);
entry.setTime(source.lastModified());
target.putNextEntry(entry);
target.closeEntry();
}
for (File nestedFile: source.listFiles())
add(nestedFile, target);
return;
}
JarEntry entry = new JarEntry(source.getPath().replace("\\", "/"));
entry.setTime(source.lastModified());
target.putNextEntry(entry);
in = new BufferedInputStream(new FileInputStream(source));
byte[] buffer = new byte[1024];
while (true)
{
int count = in.read(buffer);
if (count == -1)
break;
target.write(buffer, 0, count);
}
target.closeEntry();
}
finally
{
if (in != null)
in.close();
}
}
Il y a une autre "bizarrerie" à faire attention: tous les noms de JarEntry ne doivent PAS commencer par "/".
Par exemple: Le nom d'entrée du fichier JAR pour le fichier manifeste est "META-INF/MANIFEST.MF" et non "/META-INF/MANIFEST.MF".
La même règle doit être suivie pour toutes les entrées de bocal.
Vous pouvez le faire avec ce code:
public void write(File[] files, String comment) throws IOException {
FileOutputStream fos = new FileOutputStream(PATH + FILE);
JarOutputStream jos = new JarOutputStream(fos, manifest);
BufferedOutputStream bos = new BufferedOutputStream(jos);
jos.setComment(comment);
for (File f : files) {
print("Writing file: " + f.toString());
BufferedReader br = new BufferedReader(new FileReader(f));
jos.putNextEntry(new JarEntry(f.getName()));
int c;
while ((c = br.read()) != -1) {
bos.write(c);
}
br.close();
bos.flush();
}
bos.close();
// JarOutputStream jor = new JarOutputStream(new FileOutputStream(PATH + FILE), manifest);
}
PATH
variable: chemin d'accès au fichier JAR
FILE
variable: nom et format
Voici un exemple de code pour créer un fichier JAR à l'aide de JarOutputStream: