4

I'm using storm with python. I used this command to run the topology locally

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

and got this error

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)

I used this command mvn dependency:tree to see the versions of slf4j and here is the part of slf4j i got

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

My 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 Answers1

3

Edited answer

I was wrong with my first suspicion that this is a problem of provided or compile scope dependencies, as you are starting the program with classpathScope=compile.

The slf4 api is found, otherwise the error message would have been a ClassNotFoundError.

The problem is that log4j wants to call the following method:

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

which is defined in the slf4j api in version 1.7.5 (it's in there since version 1.3 according to the Javadocs).

The only explanation for this error is that there must be another version of slf4j-api.jar on your classpath which does not yet have this method and which is used when loading the LocationAwareLogger interface.

Please check the output of

mvn dependency:tree

for other occurrences of slf4j-api, perhaps hidden somewhere in the tree.

Another possibility to find where the class is loaded from is by using the following code (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());

Update:

So when running the program with mvn exec there is a slf4j-api loaded with version 1.5.6 (welcome to the maven dependency hell). Can you show the complete pom.xml of your project? Does it have a parent pom or otherwise introduced dependencies? What happens if you explicitly add a dependency on the required version of slf4j-api by adding:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.9</version>
</dependency>

Update:

The problem comes from the exec-maven-plugin, this is loading the older version of slf4j-api. When you remove the following line from the configuration of the plugin:

<includePluginDependencies>true</includePluginDependencies>

then the actual slf4j-api is loaded. You could as well set the value to false, but that's the default value anyway. I do not think that you should need to include the plugin dependencies, when building the package of your project you do not have them either. The documentation for this parameter states:

Indicates if this plugin's dependencies should be used when executing the main class. This is useful when project dependencies are not appropriate. Using only the plugin dependencies can be particularly useful when the project is not a java project. For example a mvn project using the csharp plugins only expects to see dotnet libraries as dependencies.

So I think that removing this line or setting the value to false will solve your problem.

P.J.Meisch
  • 18,013
  • 6
  • 50
  • 66
  • thanks for replying, but my pom doesn't contain anything about slf4j . so i didn't define it provided . how can i check that ? –  May 21 '17 at 22:09
  • it is transitively required by storm, you have to make sure that your runtime environment has these libraries on the classpath. How is the dependency to storm defined? – P.J.Meisch May 22 '17 at 03:45
  • excuse me , do you mean that i should check the library folder in storm? as I checked it and found two files for slf4j i removed it. but i found those file in m2/repository/org . what should i do after that ? i post my pom in the question post. Thanks for your patience –  May 22 '17 at 22:07
  • i noticed also that the folder of slf4j-api in .m2/repository has three version 1.5.6 , 1.6.6 and 1.7.5 . is that may be a problem ? –  May 22 '17 at 22:22
  • when you change the scope for storm in your pom to `compile` does it run then? – P.J.Meisch May 23 '17 at 04:27
  • no, same error exists with this org.slf4j:slf4j-api:jar:1.7.5:compile +- org.slf4j:log4j-over-slf4j:jar:1.6.6:compile –  May 23 '17 at 14:58
  • I edited my answer, I was wrong with the scope, please check – P.J.Meisch May 23 '17 at 20:51
  • thanks , i edited the post with full mvn dependency:tree and i tried this command too mvn dependency:tree -verbose class but i don't know how can i get the benefit from the result –  May 24 '17 at 13:21
  • do you have a different version visible with mvn dependency:tree? And could you add the code I showed that prints from where the LocationAwareLogger class is loaded? – P.J.Meisch May 24 '17 at 14:07
  • excuse me , i tried two ways and got different versions . First i tried your code then run the code using eclipse and got the version jar:file:/home/user/.m2/repository/org/slf4j/slf4j-api/1.7.5‌​‌​/slf4j-api-1.7.5.j‌​ar‌​!/org/slf4j/spi/‌​Loca‌​tionAwareLogge‌​r.clas‌​s && second way : i run the project using mvn command and got jar:file:/home/user/.m2/repository/org/slf4j/slf4j-api/1.5.6‌​/slf4j-api-1.5.6.jar‌​!/org/slf4j/spi/Loca‌​tionAwareLogger.clas‌​s . this happened after comment my code and put only the code you posted . what should i do ? –  May 24 '17 at 22:44
  • same error still with adding the dependency you posted . I updated my post with full POM –  May 25 '17 at 22:02
  • This is a good answer. Thank you! Of course removing the `includePluginDependencies` line is not the only solution (you might need it for other reason). For me the solution was to reduce the classpath with a `executableDependency` section ([see one example](https://github.com/jmini/exec-maven-plugin_issue_76/blob/master/my-pom-project/pom.xml#L27)). This way the dependency that contributes the problematical `slf4j-jdk14-1.5.6.jar` to the classpath is no longer present. – Jmini Jun 01 '17 at 16:38
  • can you please help in this https://stackoverflow.com/questions/44381499/indexoutofboundsexception-index-1-size-1 ? –  Jun 06 '17 at 04:38