尝试使用 jsr 356 时出现 java.lang.linkage 错误

Posted

技术标签:

【中文标题】尝试使用 jsr 356 时出现 java.lang.linkage 错误【英文标题】:java.lang.linkage error when trying to use jsr 356 【发布时间】:2014-10-28 22:46:30 【问题描述】:

我正在尝试从部署在码头的战争中实现 jsr 356 websocket 连接。

我以此为指导:http://aredko.blogspot.com/2013/11/java-websockets-jsr-356-on-jetty-91.html

(我可以找到很多关于基本使用带有嵌入式码头服务器的 jsr 356 的教程,但没有关于在现有服务器中构建 websocket 连接的教程 - 那里有什么好的吗?)

每当我运行上面列出的代码时,我都会收到以下错误:

java.lang.LinkageError: loader constraint violation: when resolving method "org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer.configureContext(Lorg/eclipse/jetty/servlet/ServletContextHandler;)Lorg/eclipse/jetty/websocket/jsr356/server/ServerContainer;" the class loader (instance of org/eclipse/jetty/webapp/WebAppClassLoader) of the current class, com/me/stuff/data/DataServer, and the class loader (instance of org/eclipse/jetty/start/Classpath$Loader) for resolved class, org/eclipse/jetty/websocket/jsr356/server/deploy/WebSocketServerContainerInitializer, have different Class objects for the type y.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer.configureContext(Lorg/eclipse/jetty/servlet/ServletContextHandler;)Lorg/eclipse/jetty/websocket/jsr356/server/ServerContainer; used in the signature

指代代码

ServerContainer container = WebSocketServerContainerInitializer.configureContext(context);

我不知所措。我正在使用 gradle 中的以下几行来引入 websocket 的东西:

    providedCompile (
    [ group: 'javax.websocket', name: 'javax.websocket-api', version: '+'],
    [ group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '+' ]
    )

    compile (
    [ group: 'org.eclipse.jetty.websocket', name: 'javax-websocket-server-impl', version: '+'],
    [ group: 'org.eclipse.jetty.websocket', name: 'javax-websocket-client-impl', version: '+']
    )

我看到 javax-websocket-server-impl jar 和 javax.websocket-api jar 都包含 ServerContainer 类......但我只在我的 war 文件中包含其中一个。码头是从自己内部的旧版本中提取的吗?还是我完全误读了问题的根源?

我的jetty版本是:jetty-9.2.1.v20140609

【问题讨论】:

【参考方案1】:

websocket jar 不应该在您的 WAR 中。

从 WAR 的 WEB-INF/lib/ 目录中删除以下 jar。

javax.websocket-api-*.jar - javax.websocket API jar javax-websocket-server-impl-*.jar - 码头服务器 javax.websocket.server.* 实现 jar javax-websocket-client-impl - 码头 javax.websocket.* (client) jar

这是因为您正在针对javax.websocket.* API 类进行编码/编译。

API 和 API 的实现由 Jetty 自己提供。

这与您针对 servlet-api 编写代码时没有什么不同。 (即,您的 WAR 中不包含 servlet-api 和 servlet-api 的实现)

【讨论】:

以上是关于尝试使用 jsr 356 时出现 java.lang.linkage 错误的主要内容,如果未能解决你的问题,请参考以下文章

JSR 356 WebSocket 最大消息大小配置失败

码头 Websocket JSR 356 错误 403

将 Java WebSockets (JSR-356) 与 SpringBoot 集成

使用 JSR-356(websockets)的 Jetty 8 配置

Jetty 中的 JSR-356 javax websockets(嵌入式和非嵌入式)

SpringMVC中实现Bean Validation(JSR 303 JSR 349 JSR 380)