ClassNotFoundException: org/eclipse/jetty/alpn/ALPN,但我可以访问这个类
Posted
技术标签:
【中文标题】ClassNotFoundException: org/eclipse/jetty/alpn/ALPN,但我可以访问这个类【英文标题】:ClassNotFoundException: org/eclipse/jetty/alpn/ALPN, but I have access to this class 【发布时间】:2018-06-10 06:06:03 【问题描述】:我有这样的代码:
public static void main(String[] args) throws Exception
System.out.println("ALPN class: " + ALPN.class);
HelloWorldClient client = new HelloWorldClient("localhost", 10009);
这给出了这样的输出:
ALPN class: class org.eclipse.jetty.alpn.ALPN
Exception in thread "main" java.lang.IllegalArgumentException: ALPN is not configured properly. See https://github.com/grpc/grpc-java/blob/master/SECURITY.md#troubleshooting for more information.
at io.grpc.netty.GrpcSslContexts.selectApplicationProtocolConfig(GrpcSslContexts.java:163)
at io.grpc.netty.GrpcSslContexts.configure(GrpcSslContexts.java:136)
at io.grpc.netty.GrpcSslContexts.configure(GrpcSslContexts.java:124)
at io.grpc.netty.GrpcSslContexts.forClient(GrpcSslContexts.java:94)
at btcduke.node.ln.HelloWorldClient.<init>(HelloWorldClient.java:35)
at btcduke.node.ln.HelloWorldClient.main(HelloWorldClient.java:76)
Caused by: java.lang.ClassNotFoundException: org/eclipse/jetty/alpn/ALPN
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at io.grpc.netty.JettyTlsUtil.isJettyAlpnConfigured(JettyTlsUtil.java:34)
at io.grpc.netty.GrpcSslContexts.selectApplicationProtocolConfig(GrpcSslContexts.java:153)
... 5 more
HelloWorldClient 使用 grpc,看起来 grpc 正在尝试动态加载 ALPN 类。我对吗?找不到此类,所以我有错误消息。但是请看一下,我可以访问这个类(我在第一行打印这个类)。有谁知道为什么会这样?我不知道:/
我通过添加 VM 参数“-Xbootclasspath/p:”来运行配置选项彻底解决了这个问题,但我不明白为什么我需要这样做,而且我认为这不是优雅的方法。
【问题讨论】:
您是否阅读了错误消息中以“ALPN 配置不正确”开头的部分? 您认为org/eclipse/jetty/alpn/ALPN
是该类的正确名称吗?
在进行任何猜测之前:查看由 forName 方法调用引发的 ClassNotFoundException 的错误消息。它显示了该调用中给出的名称字符串。斜杠是错误的 - 你应该有句点来分隔包名。
【参考方案1】:
记录在https://www.eclipse.org/jetty/documentation/jetty-9/index.php#alpn-chapter
适用于 Java 8,最高包括 1.8.0_242。
您必须为您的特定 JVM 使用 alpn-boot
提供程序,因为它会修改 OpenJDK 类以启用对 ALPN 的支持。
查看 ALPN 到 OpenJDK 的版本列表:https://www.eclipse.org/jetty/documentation/jetty-9/index.html#alpn-versions
这个alpn-boot-<ver>.jar
需要在JVM 命令行上使用-Xbootclasspath/p:
选项。
您还将在您的特定版本的 Jetty 服务器的正常服务器类路径上使用 jetty-alpn-openjdk8-server-<ver>.jar
。
适用于 1.8.0_252 及更高版本的 Java 8(包括 Java 9+)。
对于包含 1.8.0_252 及更高版本的 Java 8,此提供程序使用 Java 9(见下文)中引入的标准 OpenJDK ALPN API,这些 API 已向后移植到 1.8.0_252,并且不需要 -Xbootclasspath/p:
命令行选项
对于此操作模式,请在您的服务器类路径中使用 jetty-alpn-java-server-<ver>.jar
工件。
【讨论】:
不过,这不是 OP 的问题。 这正是 OP 遇到的问题。org.eclipse.jetty.alpn.ALPN
类没有按照你想象的方式加载。它有一个引导类路径依赖项,阻止它正常加载。
ClassNotFoundException 的错误消息列出了 Class.forName 的参数。我认为类名没有斜杠作为包名之间的分隔符。不过,它可能来自配置文件。
谢谢。我添加了 VM 参数“-Xbootclasspath/p:”来运行配置选项。问题消失了,但我不明白为什么我需要这样做,而且我认为这不是优雅的方法。也许这是因为出于某种原因,必须在加载我的主类之前加载这个类?
@CD -Xbootclasspath/p:
选项甚至在 JVM 自己的类之前加载类。这是由 ALPN 层完成的,以修改 JVM SSL 类以添加 ALPN 支持。 (JVM 中第一次支持 ALPN 是 Java 9)【参考方案2】:
如果您收到错误消息“ALPN 未正确配置”或“Jetty ALPN/NPN 未正确配置”,很可能意味着:
与 ALPN 相关的 dependencies 要么不存在于类路径中 或者存在类路径冲突 或者由于依赖管理使用了错误的版本。
仔细查看提供的堆栈跟踪,它表明您需要正确配置“ALPN”
Caused by: java.lang.ClassNotFoundException:
org/eclipse/jetty/alpn/ALPN
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at
io.grpc.netty.JettyTlsUtil.isJettyAlpnConfigured(JettyTlsUtil.java:34)
【讨论】:
以上是关于ClassNotFoundException: org/eclipse/jetty/alpn/ALPN,但我可以访问这个类的主要内容,如果未能解决你的问题,请参考以下文章
ClassNotFoundException:org.sqlite.JDBC
ClassNotFoundException和NoClassDefFoundError
ClassNotFoundException和NoClassDefFoundError