NoSuchMethodError:org.slf4j

时间:2017-05-20 21:37:00

标签: java python maven apache-storm

我使用python风暴。我使用此命令在本地运行拓扑

mvn compile exec:java -Dexec.classpathScope=compile -Dexec.mainClass=my.Topology

并收到此错误

java.lang.NoSuchMethodError: org.slf4j.spi.LocationAwareLogger.log(Lorg/slf4j/Marker;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/Object;Ljava/lang/Throwable;)V
at org.apache.log4j.Category.differentiatedLog(Category.java:186)
at org.apache.log4j.Category.info(Category.java:229)

我使用此命令mvn dependency:tree查看slf4j的版本 这是slf4j我得到的部分

org.apache.storm:storm-core:jar:0.9.6:provided
[INFO]    +- org.clojure:clojure:jar:1.5.1:provided
[INFO]    +- clj-time:clj-time:jar:0.4.1:provided
[INFO]    +- joda-time:joda-time:jar:2.0:provided
[INFO]    +- compojure:compojure:jar:1.1.3:provided
[INFO]    +- org.clojure:core.incubator:jar:0.1.0:provided
[INFO]    +- org.clojure:tools.macro:jar:0.1.0:provided
[INFO]    +- clout:clout:jar:1.0.1:provided
[INFO]    +- ring:ring-core:jar:1.1.5:provided
[INFO]    +- commons-fileupload:commons-fileupload:jar:1.2.1:provided
[INFO]    +- javax.servlet:servlet-api:jar:2.5:provided
[INFO]    +- hiccup:hiccup:jar:0.3.6:provided
[INFO]    +- ring:ring-devel:jar:0.3.11:provided
[INFO]    +- clj-stacktrace:clj-stacktrace:jar:0.2.2:provided
[INFO]    +- ring:ring-jetty-adapter:jar:0.3.11:provided
[INFO]    +- ring:ring-servlet:jar:0.3.11:provided
[INFO]    +- org.mortbay.jetty:jetty:jar:6.1.26:provided
[INFO]    +- org.mortbay.jetty:jetty-util:jar:6.1.26:provided
[INFO]    +- org.clojure:tools.logging:jar:0.2.3:provided
[INFO]    +- org.clojure:math.numeric-tower:jar:0.0.1:provided
[INFO]    +- org.clojure:tools.cli:jar:0.2.4:provided
[INFO]    +- commons-io:commons-io:jar:2.4:provided
[INFO]    +- org.apache.commons:commons-exec:jar:1.1:provided
[INFO]    +- commons-lang:commons-lang:jar:2.5:provided
[INFO]    +- com.googlecode.json-simple:json-simple:jar:1.1:provided
[INFO]    +- com.twitter:carbonite:jar:1.4.0:provided
[INFO]    +- com.esotericsoftware.kryo:kryo:jar:2.21:provided
[INFO]    +- 
  com.esotericsoftware.reflectasm:reflectasm:jar:shaded:1.07:provided
[INFO]    +- org.ow2.asm:asm:jar:4.0:provided
[INFO]    +- com.esotericsoftware.minlog:minlog:jar:1.2:provided
[INFO]    +- org.objenesis:objenesis:jar:1.2:provided
[INFO]    +- com.twitter:chill-java:jar:0.3.5:provided
[INFO]    +- org.yaml:snakeyaml:jar:1.11:provided
[INFO]    +- commons-logging:commons-logging:jar:1.1.3:provided
[INFO]    +- commons-codec:commons-codec:jar:1.6:provided
[INFO]    +- com.googlecode.disruptor:disruptor:jar:2.10.4:provided
[INFO]    +- org.jgrapht:jgrapht-core:jar:0.9.0:provided
[INFO]    +- ch.qos.logback:logback-classic:jar:1.0.13:provided
[INFO]    +- ch.qos.logback:logback-core:jar:1.0.13:provided
[INFO]    +- org.slf4j:slf4j-api:jar:1.7.5:provided
[INFO]    +- org.slf4j:log4j-over-slf4j:jar:1.6.6:provided
[INFO]    \- jline:jline:jar:2.11:provided

我的POM

<project xmlns="http://maven.apache.org/POM/4.0.0" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Sim</groupId>
<artifactId>Project</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>Pro</name>
<url>http://maven.apache.org</url>
<dependencies>
  <dependency>
    <groupId>org.apache.storm</groupId>
    <artifactId>storm-core</artifactId>
    <version>0.9.6</version>
    <scope>provided</scope>
  </dependency>
  </dependencies>
  <build>
    <resources>
      <resource>
        <directory> ${basedir}/multilang</directory>
      </resource>
    </resources>
<plugins>
 <plugin>
  <artifactId>maven-assembly-plugin</artifactId>
   <configuration>
     <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
             <groupId>org.codehaus.mojo</groupId>
             <artifactId>exec-maven-plugin</artifactId>
             <version>1.5.0</version>
             <executions>
                 <execution>
                     <goals>
                        <goal>exec</goal>
                     </goals>
                 </execution>
             </executions>
            <configuration>
                <executable>java</executable>
  <includeProjectDependencies>true</includeProjectDependencies>
  <includePluginDependencies>true</includePluginDependencies>
  <classpathScope>compile</classpathScope>                                  
  <mainClass>Sim.Topology</mainClass>
                          </configuration>
                    </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
                            <version>2.3</version>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>
    </plugins>

1 个答案:

答案 0 :(得分:2)

编辑回答

我首先怀疑这是提供或编译范围依赖性的问题,因为您正在使用classpathScope=compile启动程序。

找到slf4 api,否则错误消息可能是ClassNotFoundError

问题是log4j想要调用以下方法:

void log(Marker marker, String fqcn, int level, String message, Object[] argArray, Throwable t)

在1.7.5版本的slf4j api中定义(根据Javadocs版本在1.3版本中)。

这个错误的唯一解释是你的类路径上必须有另一个版本的slf4j-api.jar,它还没有这个方法,并且在加载LocationAwareLogger接口时会使用它。

请检查

的输出
mvn dependency:tree

对于slf4j-api的其他事件,可能隐藏在树中的某个地方。

找到加载类的位置的另一种可能性是使用以下代码(taking from this question):

    Class clazz = Class.forName("org.slf4j.spi.LocationAwareLogger");
    URL resourceUrl = clazz.getResource("/" + clazz.getCanonicalName().replace(".", "/") + ".class");
    System.out.println(resourceUrl.toString());

<强>更新

因此,当使用mvn exec运行程序时,有一个加载版本1.5.6的slf4j-api(欢迎来到maven依赖地狱)。你能展示你项目的完整pom.xml吗?它是否有父pom或其他引入的依赖项?如果通过添加:

显式添加对slf4j-api所需版本的依赖性,会发生什么
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.9</version>
</dependency>

<强>更新

问题来自exec-maven-plugin,这是加载旧版本的slf4j-api。从插件的配置中删除以下行时:

<includePluginDependencies>true</includePluginDependencies>

然后加载实际的slf4j-api。您也可以将值设置为 false ,但这仍然是默认值。我认为您不需要包含插件依赖项,在构建项目包时也没有它们。该参数的文档说明:

  

指示在执行主类时是否应使用此插件的依赖项。当项目依赖性不合适时,这很有用。当项目不是Java项目时,仅使用插件依赖项特别有用。例如,使用csharp插件的mvn项目只希望将dotnet库视为依赖项。

所以我认为删除这一行或将值设置为false将解决您的问题。