H2O.ai h2o-genmodel.jar contains sl4j binding

最后都变了- 提交于 2019-12-11 16:31:57

问题


When using the h2o-genmodel.jar (either from maven central or that is output when generating a mojo) SLF4j gives the error

SLF4J: Class path contains multiple SLF4J bindings
SLF4J: Found binding in [jar:file:~/.ivy2/cache/org.slf4j/slf4j-log4j12/jars/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.

Using maven or SBT's transitive dependency exclusion doesn't work, so right now I'm using the jar output with the mojo and removing the dependencies from inside the jar by hand.

Is there some better way to use h2o modelgen without having to manually mess with the inside of the jar (using maven instead would be preferable)?


回答1:


So this ended up being a case of too hasty to post on SO

Using maven or SBT's transitive dependency exclusion doesn't work

ended up not being true. I simply needed to refresh SBT one time more.

I'll leave this question up though for reference. mvnrepository.com might indicate that this is a pom dependency and you should include the dependency like

libraryDependencies += "ai.h2o" % "h2o-genmodel" % "3.18.0.11" % "runtime" pomOnly()

or

<dependency>
    <groupId>ai.h2o</groupId>
    <artifactId>h2o-genmodel</artifactId>
    <version>3.18.0.11</version>
    <type>pom</type>
    <scope>runtime</scope>
</dependency>

but it seems from experimentation that that does not work, and hex.genmodel... packages will not be available

To get the dependencies working and not pull in the slf4j binding you should use

libraryDependencies += "ai.h2o" % "h2o-genmodel" % "3.18.0.11" exclude("org.slf4j", "slf4j-log4j12")

or

<dependency>
    <groupId>ai.h2o</groupId>
    <artifactId>h2o-genmodel</artifactId>
    <version>3.18.0.11</version>
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
    </exclusions>
</dependency>



回答2:


h2o-genmodel it's a pom type dependency. That means you use it as an aggregator for multiple dependencies to make your life easier. Your problem arise from the fact that the ai.h2o:deepwater-backend-api:jar:1.0.4 dependency of h2o-genmodel has a transient dependency to org.slf4j:slf4j-log4j12:jar:1.7.5. You can debug the dependency hierarchy by using the dependency maven plugin, run the following command:

> mvn dependency:tree
...
[INFO] \- ai.h2o:h2o-genmodel:pom:3.18.0.11
[INFO]    +- net.sf.opencsv:opencsv:jar:2.3
[INFO]    +- com.google.code.gson:gson:jar:2.6.2
[INFO]    +- com.google.protobuf.nano:protobuf-javanano:jar:3.1.0
[INFO]    \- ai.h2o:deepwater-backend-api:jar:1.0.4
[INFO]       \- org.slf4j:slf4j-log4j12:jar:1.7.5
[INFO]          +- org.slf4j:slf4j-api:jar:1.7.5
[INFO]          \- log4j:log4j:jar:1.2.17

To fix this, you can exclude the slf4j-log4j12 dependency from h2o-genmodel dependency with this:

    <dependency>
        <groupId>ai.h2o</groupId>
        <artifactId>h2o-genmodel</artifactId>
        <version>3.18.0.11</version>
        <type>pom</type>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

You can run again the maven dependency tree command to check how many slf4j bindings remained.

Because the error complains of multiple slf4j bindings I assume once you make sure there is only one slf4j binding in the dependency tree everything will be fine at runtime.

UPDATE:

More details why this solution works:
First, the ai.h2o:h2o-genmodel dependency is declared as type pom is because this is how it is published. A maven artefact of type pom is used in two cases: as an aggregator for submodules or as an aggregator for dependencies. In this case, the pom type is used in second scenario, to pack dependencies for ai.h2o:h2o-genmodel. To varify this, you can check your maven local repository (most likely at ${user.home}/.m2/repository/ai/h2o/h2o-genmodel/3.18.0.11 there is no jar file, only the .pom. Please read this documentation Introduction to the Dependency Mechanism and POM Relationships

Another issue, might be the fact that ai.h2o:h2o-genmodel doesn't adhere to recommended way to wrap dependencies because it doesn't use <dependencyManagement>, but instead is using <dependencies>. Because of this, the details on maven documentation is not working exactly as expected. To overcome this, you have to use ai.h2o:h2o-genmodel explicitly on <dependencies> and adjust manually the scope of each dependency behind it. I strongly suggest to run the mvn dependency:tree because will display the scope of each dependency. In my output I removed the scopes because I didn't want it to polute the answer.

In conclusion, why in my solution works with dependency declared as pom and in @kag0 not as pom is because the ai.h2o:h2o-genmodel is of type pom and maven treat it in same way becaue when the <type> is missing it infers it from the artefact pom.



来源:https://stackoverflow.com/questions/50749476/h2o-ai-h2o-genmodel-jar-contains-sl4j-binding

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!