2015-04-26 80 views
1

我想使用Jetty服務器運行Jersey REST服務。當我在IntelliJ中運行時,出現以下錯誤:在IntelliJ但不是Eclipse的NoSuchMethodError

java.lang.NoSuchMethodError: javax.ws.rs.core.Application.getProperties()Ljava/util/Map; 
    at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:309) 
    at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:338) 
    at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:171) 
    at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:363) 
    at javax.servlet.GenericServlet.init(GenericServlet.java:244) 
    etc... 
    at service.WebserviceRunner.start(WebserviceRunner.java:37) 

如果我在Eclipse中運行相同的項目,它運行良好。爲什麼IDE會有所作爲?


WebserviceRunner.java

import org.eclipse.jetty.server.Server; 
import org.eclipse.jetty.server.handler.HandlerCollection; 
import org.eclipse.jetty.servlet.ServletHolder; 
import org.eclipse.jetty.webapp.WebAppContext; 
import org.glassfish.jersey.server.ServerProperties; 
import org.glassfish.jersey.servlet.ServletContainer; 

public class WebserviceRunner { 

    private Server server; 
    private int port; 
    private String host; 

    public WebserviceRunner(String host, int port) { 
     this.server = new Server(port); 
     this.host = host; 
     this.port = port; 
    } 

    public void start() throws Exception { 
     HandlerCollection handlers = new HandlerCollection(); 
     WebAppContext handler = new WebAppContext(); 

     handler.setContextPath("/"); 
     handler.setResourceBase("./"); 
     handler.setClassLoader(Thread.currentThread().getContextClassLoader()); 

     ServletHolder restServlet = handler.addServlet(ServletContainer.class, "/*"); 
     restServlet.setInitOrder(0); 
     restServlet.setInitParameter(ServerProperties.PROVIDER_PACKAGES,"resource"); 

     handlers.addHandler(handler); 

     server.setHandler(handlers); 
     server.start(); 
     System.out.println("API started... at 'http://" + getHostAndPort() + "'"); 
    } 

    private String getHostAndPort() { 
     return host + ":" + port; 
    } 

    public static void main(String[] args) throws Exception { 
     new WebserviceRunner("localhost", 8315).start(); 
    } 
} 

的build.gradle

apply plugin: 'java' 
apply plugin: 'jetty' 
apply plugin: 'eclipse' 
apply plugin: 'idea' 
apply plugin: 'war' 

repositories { 
    mavenCentral() 
} 

dependencies { 
    compile 'org.glassfish.jersey.core:jersey-server:2.17' 
    compile 'org.glassfish.jersey.containers:jersey-container-servlet-core:2.17' 

    compile 'org.javassist:javassist:3.15.0-GA' 
    compile 'javax.ws.rs:javax.ws.rs-api:2.0.1' 
    compile 'javax.inject:javax.inject:1' 
    compile 'com.google.code.gson:gson:2.2.2' 
    compile 'com.google.guava:guava:10.0' 
    compile 'com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.3.0' 
    testCompile group: 'junit', name: 'junit', version: '4.11' 

    def jettyVersion = '7.2.2.v20101205'; 
    compile "org.eclipse.jetty:jetty-server:${jettyVersion}" 
    compile "org.eclipse.jetty:jetty-webapp:${jettyVersion}" 
    compile "org.eclipse.jetty:jetty-servlet:${jettyVersion}" 
    compile "org.eclipse.jetty:jetty-servlets:${jettyVersion}" 
    compile "org.eclipse.jetty:jetty-annotations:${jettyVersion}" 
    compile 'org.mortbay.jetty:jsp-2.1-glassfish:2.1.v20100127' 
    compile 'javax.servlet:jstl:1.2' 
    compile 'javax.servlet:javax.servlet-api:3.0.1' 
} 

注:我認爲這是事做有兩個不同版本的同樣的應用程序類在我的類路徑。爲什麼當我只導入一個?

enter image description here

+0

你知道一個或其他IDE是否使用Proguard進行代碼混淆?這可能會有所作爲... – Trinimon

+0

@Trinimon我在兩個IDE上運行默認設置,我不知道如何找出。我認爲在同一個類路徑中有兩個版本的類是一個問題,Eclipse似乎選擇了正確的,但不是IntelliJ。 – Edd

+0

通常你會在你的項目中找到一個'proguard'文件。導入庫的公共方法不應該被混淆,所以你通常會添加類似'-keep public class * extends javax.ws.rs.core。*'的東西。但看看「失蹤」班我有另一個想法...(看下面的答案) – Trinimon

回答

1

我昨天就遇到了這個問題,使用Maven,沒有搖籃。 你是對的,問題是由於在同一個包中有兩個具有相同類名的jar:java.ws.rs.core.Application。

我能夠通過搜索依賴關係樹並找到哪個jar的依賴項引入了澤西版應用程序並使用Maven的排除標記排除它來解決它。

你的情況很明顯:類加載器看到兩個版本的java.ws.rs.core.Application並從org.glassfish.jersey.core中選擇一個不是你想要的。

至於它爲什麼在Eclipse中工作,而不是在IDEA中,類加載器不能保證加載類的順序,使用兩個不同的類加載器可能會按不同的順序加載類,並且如果存在重複在不同的行爲。

相關問題