Je tente de charger une classe à partir de JAR représenté sous la forme d'un tableau byte [] au moment de l'exécution.
Je connais deux choses sur la classe à la charge:
1. Il met en oeuvre « RequiredInterface »
2. Je sais que c'est un nom qualifié: « sample.TestJarLoadingClass »
j'ai trouvé le solution dans lequel je dois étendre ClassLoader mais il jette:ClassNotFoundException lors de la tentative de chargement de la classe à partir du fichier JAR externe au moment de l'exécution
Exception in thread "main" java.lang.ClassNotFoundException: sample.TestJarLoadingClass
at java.lang.ClassLoader.findClass(ClassLoader.java:530)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at tasks.Main.main(Main.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
chaque fois que je veux charger la classe.
Quelle peut être la raison de cette situation et comment puis-je m'en débarrasser?
Toute aide très appréciée
méthode principale:
public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException {
Path path = Paths.get("src/main/java/tasks/sample.jar");
RequiredInterface requiredInterface = (RequiredInterface) Class.forName("sample.TestJarLoadingClass", true, new ByteClassLoader(Files.readAllBytes(path))).newInstance();
}
classe personnalisée chargeur:
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class ByteClassLoader extends ClassLoader {
private final byte[] jarBytes;
private final Set<String> names;
public ByteClassLoader(byte[] jarBytes) throws IOException {
this.jarBytes = jarBytes;
this.names = loadNames(jarBytes);
}
private Set<String> loadNames(byte[] jarBytes) throws IOException {
Set<String> set = new HashSet<>();
try (ZipInputStream jis = new ZipInputStream(new ByteArrayInputStream(jarBytes))) {
ZipEntry entry;
while ((entry = jis.getNextEntry()) != null) {
set.add(entry.getName());
}
}
return Collections.unmodifiableSet(set);
}
@Override
public InputStream getResourceAsStream(String resourceName) {
if (!names.contains(resourceName)) {
return null;
}
boolean found = false;
ZipInputStream zipInputStream = null;
try {
zipInputStream = new ZipInputStream(new ByteArrayInputStream(jarBytes));
ZipEntry entry;
while ((entry = zipInputStream.getNextEntry()) != null) {
if (entry.getName().equals(resourceName)) {
found = true;
return zipInputStream;
}
}
} catch (IOException e) {;
e.printStackTrace();
} finally {
if (zipInputStream != null && !found) {
try {
zipInputStream.close();
} catch (IOException e) {;
e.printStackTrace();
}
}
}
return null;
}
}
RequiredInterface:
public interface RequiredInterface {
String method();
}
classe dans le fichier JAR:
package sample;
public class TestJarLoadingClass implements RequiredInterface {
@Override
public String method() {
return "works!";
}
}
J'ai utilisé le code que vous avez posté sur ma machine et tout a fonctionné. Pourriez-vous s'il vous plaît publier l'exception exacte que vous avez? Vérifiez également si le chemin que vous utilisez indique ** vraiment ** à jar contenant la classe que vous voulez charger. –
Ok, j'ai posté tout le message d'exception. J'ai vérifié toutes les erreurs "stupides" possibles, tout devrait fonctionner. S'il vous plaît vérifiez si vous n'avez pas la classe nécessaire pour être chargé dans une gamme de votre chargeur de classe. –
Oui, vous avez raison, par erreur, j'ai ajouté la dépendance à jar avec la classe au lieu de jar avec l'interface. Désolé –