2017-01-24 5 views
0

Spring Boot Maven Plugin. LayoutFactory neues Feature. Verfügbar seit 1.5.0.M1.Custom Launcher ClassNotFound-Ausnahme bei Verwendung des benutzerdefinierten Layouts

Ich habe Probleme, wenn ich einen benutzerdefinierten Launcher im Custom-Layout definieren:

@Override public String getLauncherClassName() { return "com.mycompany.CustomLauncher"; } 

Wenn ich meinen benutzerdefinierten Launcher in den Boot-Anwendung Quellen umfassen, um es zu BOOT-INF/classes neu verpackt wird, und wenn Ich versuche, das JAR auszuführen, das mit einer ClassNotFound-Ausnahme fehlschlägt.

Ich habe den Repackager-Code gelesen, aber ich kann keinen Haken finden, der es ermöglicht, eine bestimmte Klasse selektiv von der Repaketierungssequenz auszuschließen. Wenn ich die getRepackagedClassesLocation-Methode in meinem Layout überschreibe, wird die Boot-Hauptklasse von einem anderen Classloader geladen und schlägt bei SpringBoot ClassNotFound fehl.

Gibt es eine Möglichkeit, dass ich den Launcher aus der BOOT-INF/Klassen Repackaging zwingen kann?

UPDATE 1

@Override 
public void writeLoadedClasses(LoaderClassesWriter writer) throws IOException 
{ 
    String name = PropertiesLauncherInternal.class.getName().replaceAll("\\.", "\\\\") + ".class"; 
    InputStream inputStream = PropertiesLauncherInternal.class.getResourceAsStream(PropertiesLauncherInternal.class.getSimpleName() + ".class"); 
    writer.writeEntry(name, inputStream); 
    writer.writeLoaderClasses(); 
} 

Um zu sehen, dass der Code zugänglich ist ich diesen Test hinzugefügt haben:

JarInputStream is = new JarInputStream(new FileInputStream(new File("c:/git/dev/framework/boot/target/boot-current-SNAPSHOT.jar")), true); 
    JarEntry entry = null; 
    while (null != (entry = is.getNextJarEntry())) 
    { 
     System.out.println(entry.getName() + "-" + entry.getCrc()); 
    } 

    URL url = new File("c:/git/dev/framework/boot/target/boot-current-SNAPSHOT.jar").toURL(); 
    URL[] urls = new URL[] { url }; 
    ClassLoader cl = new URLClassLoader(urls); 
    Class cls = cl.loadClass("com.test.Boot"); 
    Class cls = cl.loadClass("com.launcher.PropertiesLauncherInternal"); 

Für die erste Schleife ich folgendes Protokoll erhalten:

BOOT-INF/--1 
BOOT-INF/classes/--1 
BOOT-INF/classes/com/-0 
BOOT-INF/classes/com/test/-0 
BOOT-INF/classes/com/test/Boot.class-2405822989 
... 
com\launcher\PropertiesLauncherInternal.class--1 

Die Nummer neben den Klassennamen ist der CRC. Ich bin mir nicht sicher, ob das relevant ist, aber die CRC-32 ist unbekannt.

Wenn die Klassenlader verwenden, ich bin in der Lage com.test.Boot zu laden, aber es scheitert auf ClassNotFoundException für die PropertiesLauncherInternal.class

Antwort

0

Anstatt es neben Ihrem Anwendungscode sollte Launchers Code in einem separaten sein Modul, das als eine Abhängigkeit von Maven-Plugin von Spring Boot deklariert ist. Dieses separate Modul sollte die Standard-Jar-Verpackung von Maven verwenden und nicht mit dem Maven-Plugin von Spring Boot neu verpackt werden.

Es gibt eine sample, die zeigt, wie Sie Dinge einrichten.

+0

Hallo Andy, ich habe es versucht, und ich bekomme meinen Launcher gepackt. Wenn ich jedoch versuche, das JAR auszuführen, erhalte ich einen ** Fehler: Hauptklasse ** konnte nicht gefunden oder geladen werden. Wenn ich dieselbe Klasse (identischen Inhalt, denselben Namen) manuell an die gleiche Stelle in der JAR kopiere, funktioniert es. Irgendeine Idee, was das Problem sein könnte? –

+0

Nein, tut mir leid. Vielleicht können Sie Code teilen, der das Problem reproduziert? –

+0

Ich habe einige Details zur ursprünglichen Frage hinzugefügt. –

Verwandte Themen