使用自定义布局时自定义启动器ClassNotFound异常

时间:2017-01-24 13:48:34

标签: maven spring-boot spring-boot-maven-plugin

Spring Boot Maven插件。 LayoutFactory新功能。自1.5.0.M1起可用。

我在自定义布局中定义自定义启动器时出现问题:

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

如果我在启动应用程序源中包含我的自定义启动程序,它会被重新打包到BOOT-INF / classes,当我尝试运行JAR时,它会因ClassNotFound异常而失败。

我一直在阅读Repackager代码,但我找不到任何允许从重新包装序列中选择性地排除给定类的钩子。如果我覆盖布局中的getRepackagedClassesLocation方法,则引导主类由不同的类加载器加载,并且在SpringBoot ClassNotFound上失败。

有什么方法可以强制启动BOOT-INF /类重新包装?

更新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();
}

为了看到代码是可访问的,我添加了这个测试:

    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");

对于第一个循环,我得到以下日志:

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

类名旁边的数字是CRC。我不确定是否相关,但CRC-32未知。

使用类加载器时,我可以加载com.test.Boot,但是对于PropertiesLauncherInternal.class,它在ClassNotFoundException上失败

1 个答案:

答案 0 :(得分:0)

您的启动器代码应该位于一个单独的模块中,而不是将其与应用程序代码放在一起,而该模块被声明为Spring Boot的Maven插件的依赖项。这个单独的模块应该使用Maven的标准jar包装,不应该使用Spring Boot的Maven插件重新打包。

有一个sample,展示了如何进行设置。

相关问题