I'm using SBT to manage dependencies. I added 2 jars AAA and BBB into my project. However, both AAA and BBB have a class with exact same name and path like com.ccc.ddd.eee.fff.foo.java.
Now, the compiler does NOT complain. However, when I import foo.java, it always comes from jar AAA although, unfortunately, I want it to come from jar BBB.
Any suggestions about how to solve this puzzle? Thank you in advance.
EDIT:
I was using libraryDependencies +=, managed dependencies.
You didn't say how the 2 jars were added; it would be helpful to see your build.sbt.
That said, the classpath is affected by the order in which you list the dependencies. If you are using unmanaged dependencies, and you want a specific version of a class to be found, list that library dependency first.
If they were specified as managed dependencies, it is more common to try something like:
libraryDependencies += "foo" % "bar" % "x.y.z" exclude("org.domain", "AAA")
or:
ivyXML :=
<dependencies>
<dependency org="org.domain" name="AAA" rev="x.y.z">
<exclude module="activation"/>
</dependency>
</dependencies>
There is more information here: http://www.scala-sbt.org/release/docs/Library-Management.html
Related
Consider the below scenario where i am getting an unexpected error and unable to fix it.
In Opendaylight architype project, I just used a class(Say test.class from io-example dependency) when I just declared only one dependency (i.e io-example) in the pom.xml, there is no error.
But if i add one more dependency (io-example-api) in the pom.xml, I am getting java.lang.NoClassDefFoundError: io/example/test.class
at org.opendaylight.gnmi.impl.base.OpenconfigInter
..................................................
..................................................
Caused by: java.lang.ClassNotFoundException: io.example.Test cannot be found by org.opendaylight
I found that io.example-api has the io-example as the dependency.. Summarize the issue, If i have the io-example alone in the pom.xml, there is no issue. If I have both io-example and io-example-api in the pom.xml, I am getting the NoclassDef error.
Even I have tried the exclusion option in the dependency section, Nothing works.
Thanks in advance...
Edited:
classname : io.grpc.Context
Dependencies :
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-context</artifactId>
<version>1.38.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-api</artifactId>
<version>1.38.0</version>
</dependency>
In karaf container, I ran the "package:exports" commands and the results are,
opendaylight-user#root>package:exports -p io.grpc
io.grpc 0.0.0 354 wrap_file__home_verizon_gnmi_gnmi_karaf_target_assembly_system_io_grpc_grpc-api_1.38.0_grpc-api-1.38.0.jar
io.grpc 0.0.0 355 wrap_file__home_verizon_gnmi_gnmi_karaf_target_assembly_system_io_grpc_grpc-context_1.38.0_grpc-context-1.38.0.ja
opendaylight-user#root>package:exports -d
io.grpc 0.0.0 354 355
You can see that, io.grpc package exported by two bundles (354 and
355)..
A common cause for ClassNotFoundException in OSGi and Karaf is that multiple bundles export the same package with the same version. This causes only one of them be imported which may or may not contain your Test class.
Check which packages export io.example with package:exports command:
packages:exports -p io.example
I am guessing that adding the dependency causes your bundle to import the package io.example from io-example-api instead of io-example.
Solution for this would be to make sure only one bundle exports io.example package.
[Edit] I am unfamiliar with grpc but there seems to be issue on github about this and some workarounds that you could look in to.
You could also try creating a bundle that embeds these problematic dependencies and exports the packages for other bundles to use.
Create a new bundle project using archetype karaf-bundle-archetype
Add grpc-context and grpc-api dependencies
Configure maven-bundle-plugin to emped the grpc dependencies and export io.grpc package along with its sub packages.
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${maven-bundle-plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>
${project.groupId}.${project.artifactId}
</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Bundle-Activator>com.example.Activator</Bundle-Activator>
<Import-Package>
*;resolution:=optional
</Import-Package>
<Export-Package>
io.grpc*;-split-package:=merge-first
</Export-Package>
<Emped-Dependency>
grpc-context;scope=compile|runtime;inline=true,
grpc-api;scope=compile|runtime;inline=true
</Emped-Dependency>
</instructions>
</configuration>
</plugin>
Managed to install the bundle successfully to Karaf 4.2.11 and "use" the exported io.grpc.Context class in the bundle and in another bundle.
Simply called this from the Activator of two bundles
Context grpcContext = Context.current();
System.out.println(grpcContext.getClass().getName());
I used the latest flink version(1.10.0) and sbt(1.3.7). I have this exception when upload a job with streaming sql query:
Caused by: java.lang.ClassCastException:
org.codehaus.janino.CompilerFactory cannot be cast to
org.codehaus.commons.compiler.ICompilerFactory
at org.codehaus.commons.compiler.CompilerFactoryFactory.getCompilerFactory(CompilerFactoryFactory.java:129)
at org.codehaus.commons.compiler.CompilerFactoryFactory.getDefaultCompilerFactory(CompilerFactoryFactory.java:79)
at org.apache.calcite.rel.metadata.JaninoRelMetadataProvider.compile(JaninoRelMetadataProvider.java:432)
When I running main class with sbt run it works perfectly. I made jar with the sbt assembly command and I have conflicts between libraries. For this reason add this in the build.sbt:
assemblyMergeStrategy in assembly := {
case PathList("META-INF", xs # _*) => MergeStrategy.discard
case x => MergeStrategy.first
}
I read a similar case with hive connector https://issues.apache.org/jira/browse/FLINK-14849 and this is the answer:
After https://issues.apache.org/jira/browse/FLINK-13749 , flink-client will use default child-first resolve-order.
If user jar has some conflict dependents, there will be some problem.
My question is: How to resolve these conflicts? Any assembly merge strategy suggest for this case?
Help would be appreciated.
I faced the same issue and the following solution helped me get through :
assembly / assemblyMergeStrategy := {
case PathList("org", "codehaus", "janino", "CompilerFactory.class") => MergeStrategy.discard // discard
case x => MergeStrategy.first // first
}
Also, took help from the this link.
The above addition needs to be done in sbt.build file and make sure you're building using assembly command.
In case one is building using package-bin in case of legacy applications, follow this link.
Another solution includes checking the scope of the flink libraries. If by any chance you have accidentally pushed libraries that were earlier set to 'provided' with something like 'compile', do revert the changes and test.
Hope this helps.
I have same problem.
Maybe you have package your code with flink-table-planner_${scala.binary.version}, so you need to change your maven config with those settings:
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-planner_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-planner-blink_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-planner_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
I had the same issue. My problem was, that I added the dependency
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-planner_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
without the provided scope. Therefore, maven packaged it in my jar, which lead to the ClassCastException when trying to submit the job to my local flink cluster.
In my project, I have exactly one dependency (right now, it's early!) - Hibernate. In my Ivy config, I have the following:
<dependencies>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency org="org.hibernate" name="hibernate-core" rev="5.4.0.Final" conf="sources->sources"/>
<dependency org="org.hibernate" name="hibernate-core" rev="5.4.0.Final" conf="binaries->default"/>
</dependencies>
And in my build.xml, I have this:
<ivy:retrieve conf="sources" pattern="war/WEB-INF/lib/[conf]/[artifact](-[classifier]).[ext]"/>
<ivy:retrieve conf="binaries" pattern="war/WEB-INF/lib/[artifact](-[classifier]).[ext]"/>
Now, in my lib folder, I have a folder called sources with exactly one jar, hibernate-core-sources.jar - perfect!! But in the lib folder itself, I don't have exactly one jar - I have 18 jars, one for each of Hibernate's dependencies (and grandparent dependencies, etc.)
What I'd really like to see is something like hibernate-core.jar and hibernate-core-deps.jar.
Is something like this possible? If it isn't, would it be possible to have it be hibernate-core.jar and my-app-deps.jar? And if THAT isn't possible, can it just bundle it all into a single my-app-deps.jar?
I'm not very experienced with Ivy, so the more explicit your answer, the better!
It's possible, but you have to be aware that when you build the classpath you may end um missing some classes and having NoClassDefFoundError thrown at runtime.
The solution is to call ivy resolve once with transitive set to false, and second time with it being set to true (which is default). After each of these you have to call retrieve but with different retrieve patterns, so the non-transitive (hibernate-core.jar) to lib folder and transitive to a temp folder from which you could create hibernate-core-deps.jar.
I changed my struts2 version from 2.3.14 to 2.3.16.1, it seems that newest version does not support ServletRequestAware and ServletResponseAware anymore, what should I do? I could not find anything online.
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.3.16.1</version>
<type>jar</type>
</dependency>
Code
import org.apache.struts2.interceptor.ServletRequestAware;
public class MyExample implements ServletRequestAware, ServletResponseAware {
Error
package org.apache.struts2.interceptor does not exist.
When I try to find a dependency for it Maven shows the latest version of Struts2 which is supporting it is 2.3.14!
You probably have some problem with the libraries included in your project;
Be sure to erase all the old JARs from the classpath (your WAR / EAR and shared libs on the AS;
run Clean Project in your IDE;
download Struts2.3.16.1 from Maven or manually from here;
check out the ServletRequestAware and ServletResponseAware Interfaces at
/struts-2.3.16.1/src/core/src/main/java/org/apache/struts2/interceptor/
, exactly where they were before ;)
E.g., output from 2.3.16.3 distribution:
$ jar tvf struts2-core-2.3.16.3.jar | grep ServletRequest
223 Fri May 02 17:23:44 EDT 2014 org/apache/struts2/interceptor/ServletRequestAware.class
It's also in the 2.3.16.1 jars.
At the Step 3 of Welcome to Struts2 add the following dependency to your pom.xml
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>X.X.X.X</version>
</dependency>
Check the file version X.X.X.X is available in the repository and downloaded to your hard drive.
In a Java Play 2.1.1 app I get the following error:
[myproject] $ update
[info] Updating {file:/C:/path/myproject/}myproject...
[info] Resolving ...
[error] impossible to get artifacts when data has not been loaded. IvyNode = com.google.guava#guava;12.0
[error] (*:update) java.lang.IllegalStateException: impossible to get artifacts when data has not been loaded. IvyNode = com.google.guava#guava;12.0
[error] Total time: 230 s, completed 17.05.2013 19:16:41
Build.scala
"com.google.guava" % "guava" % "14.0.1",
"org.mydependency" % "mydependency" % "1.0-SNAPSHOT" changing() exclude("org.jboss.netty","netty") exclude("com.google.guava", "guava") exclude("log4j", "log4j"),
The thing that causes this error (it all worked fine before) is a dependency change within mydependency:
old:
<dependency>
<groupId>com.thinkaurelius.titan</groupId>
<artifactId>titan-berkeleyje</artifactId>
<version>0.3.1</version>
</dependency>
new:
<dependency>
<groupId>com.thinkaurelius.titan</groupId>
<artifactId>titan-cassandra</artifactId>
<version>0.3.1</version>
</dependency>
I don't want guava 12.0 anyway and it is and was excluded.
Can I tell Play 2.1.1 to use a newer Ivy?
In plugins.sbt I have:
addSbtPlugin("play" % "sbt-plugin" % "2.1.1")
Temporary fix
As someone mentioned here Apache IVY error message? : impossible to get artifacts when data has not been loaded manually adding the dependency solves it: I've added
"com.google.guava" % "guava" % "12.0"
and the problem is gone.
Apparently more people had and have this issue, so I'm putting my solution as an answer:
Temporary fix
As someone mentioned here Apache IVY error message? : impossible to get artifacts when data has not been loaded manually adding the dependency solves it: I've added
"com.google.guava" % "guava" % "12.0"
and the problem is gone.
Instead of using a lower version, you could try adding this line to .sbt file:
dependencyOverrides += "com.google.guava" % "guava" % "14.0.1"
Play 2.1.x uses sbt 0.12, which uses Ivy 2.3.0-rc1, but looks like this is still an issue.
If you can come up with a reproduction steps using publicly available libraries, please open a Github issue with a link to this comment.