我有一个运行良好的Spring Boot应用程序。我编写了一个附加类,旨在验证定义的Spring上下文和附加属性的某些方面。它打算作为备用主类运行。完成分析后,将打印结果并退出。
当我执行“ Run As”->“ Spring Boot App”,然后选择该替代主类而不是默认的“ Application”类时,一切正常。
我现在需要能够从命令行执行此操作。我注意到曾经有人遇到过这个问题,here对此进行了描述,但是该解决方案对我不起作用。
就原型而言,替代类仅在src / test / java中。我构造了这样的命令行:
java -cp "target/Service.jar;target/test-classes" -Dloader.main=... org.springframework.boot.loader.PropertiesLauncher
其中“ Service.jar”是组装好的弹簧靴子罐,其本身运行良好。运行此命令时,我得到的是这样的东西:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/cli/ParseException
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.getDeclaredMethod(Class.java:2128)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:47)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
at org.springframework.boot.loader.PropertiesLauncher.main(PropertiesLauncher.java:593)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.cli.ParseException
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 7 more
请注意,备用主类没有任何Spring或SpringBoot批注。不需要在Eclipse中运行POC。
我确定ParseException类提到了SpringBoot jar中有一个包装好的jar,但是像这样运行它显然以某种方式错过了它。
更新:
我注意到“ ParseException”类是晚于CLI工件的,它不是从常规主类中引用的,而是从我的特殊替代类中引用的。为了解决这个问题,我只构建了一个命令行,为本地存储库中的“ commons-cli”工件指定了一个类路径条目。
但是,一旦我克服了这个问题,我便击中了十几个其他遗失的工件,这些原始工件很可能会被原始的springboot主类引用(几个spring-工件,jersey-server等)。我设法通过使用相同的技术来遍历每个对象,并将路径添加到本地仓库中的工件。我终于让替代主类成功执行并完成了它的工作。这导致非常烦人的命令行,而且我不明白为什么必须在类路径上手动指定这么多工件。我猜想使用PropertiesLauncher而不是默认启动器与此有关。我对这种解决方案不太满意。
答案 0 :(得分:0)
因为Spring Boot select c.hacker_id
, h.name
, count(c.hacker_id) c_count
from hackers h
join challenges c
on c.hacker_id = h.hacker_id
group
by c.hacker_id
, h.name
having c_count =
( SELECT MAX(temp1.cnt)
from
( SELECT COUNT(hacker_id) cnt
from challenges
group
by hacker_id
) temp1
)
or c_count in
(select t.cnt
from
( select count(*) cnt
from challenges
group
by hacker_id
) t
group
by t.cnt
having count(t.cnt) = 1)
order
by c_count DESC
, c.hacker_id
jar具有不同的结构Executable Jar File Structure
uber
这意味着example.jar
|
+-META-INF
| +-MANIFEST.MF
+-org
| +-springframework
| +-boot
| +-loader
| +-<spring boot loader classes>
+-BOOT-INF
+-classes
| +-mycompany
| +-project
| +-YourClasses.class
+-lib
+-dependency1.jar
+-dependency2.jar
jar具有特定的类路径和类加载器:uber
将加载:
您来自org.springframework.boot.loader.LaunchedURLClassLoader
的课程
您对BOOT-INF/classes/*
的依赖
因此,当您将BOOT-INF/lib/*
添加到alternate main class
jar的根目录中时,uber
找不到它
但是当您从IDE运行时,会发现从目录构建的LaunchedURLClassLoader
和classpath
,在IDE中,您的应用也会从另一个类加载器alternate main class
this answer在您的情况下不起作用,因为您的jdk.internal.loader.ClassLoaders$AppClassLoader
位于alternate main class
中,这意味着src/test/java
中的类不会落入jar中,它们将在构建罐子之前可用并在测试期间运行
看看E.4 PropertiesLauncher Features通知并尝试其他配置,您也可以配置classpath:)