MessageBodyProviderNotFoundException after building with maven shade plugin [solved] - java

Hi I'm building a java REST client application that uses json. There's a conflict in my dependencies: one essential dependency requires jackson databind/core/annotations 2.10.1, another essential dependency uses an older version 2.2.2.
When running the app in Eclipse, this led to a MessageBodyProviderNotFoundException. The problem was that maven included version 2.2.2 instead of 2.10.1. So I use dependency management to resolve the conflict and include version 2.10.1. Within Eclipse this solved the issue and the app runs fine.
But after building the app with the maven shade plugin, the standalone app still fails with the MessageBodyProviderNotFoundException. The exception is thrown in a part of the code requiring version 2.10.1, not in the part depending on version 2.2.2.
Any thoughts? Thanks in advance!
EDIT: I checked my local maven repository and it only contains version 2.10.1. So the problem is not that the jar somehow still includes version 2.2.2.

Problem solved. Running the app within Eclipse apparently doesn't require explicitly registering a JacksonJsonProvider, but running the standalone app does:
ClientConfig config = new ClientConfig().connectorProvider(new ApacheConnectorProvider()).register(new JacksonJsonProvider());
Client client = ClientBuilder.newBuilder().withConfig(config) ...

Related

NoSuchMethodError: org.apache.hadoop.conf.Configuration.getPassword

I have been struggling with this NoSuchMethodError in a Spark project for a while now without getting anywhere. Currently, this project is running locally using SparkNLP 3.3.0 and Spark-Core/SparkMLLib 3.1.2, both with Scala 2.12.4. Hadoop 3.2.0 is pulled in as a transitive dependency via spark-core.
What I have tried so far:
check that this method is indeed present by stepping through the code
verify uniform Scala version across all dependencies
verify that spark and hadoop versions are the same throughout (using maven dep tree and enforcer plug-in)
manually remove other versions of Hadoop from local .m2 directory
The code is running from an executable JAR which pulls in other jars to the classpath that are provided at runtime. Java version is 1.8.0_282. Maven is version 3.6.3. OS is Big Sur, 11.6 (M1).
Exception in thread "main" java.lang.NoSuchMethodError: org.apache.hadoop.conf.Configuration.getPassword(Ljava/lang/String;)[C
at org.apache.spark.SSLOptions$.$anonfun$parse$8(SSLOptions.scala:188)
at scala.Option.orElse(Option.scala:289)
at org.apache.spark.SSLOptions$.parse(SSLOptions.scala:188)
at org.apache.spark.SecurityManager.<init>(SecurityManager.scala:98)
at org.apache.spark.SparkEnv$.create(SparkEnv.scala:252)
at org.apache.spark.SparkEnv$.createDriverEnv(SparkEnv.scala:189)
at org.apache.spark.SparkContext.createSparkEnv(SparkContext.scala:277)
at org.apache.spark.SparkContext.<init>(SparkContext.scala:458)
at org.apache.spark.SparkContext$.getOrCreate(SparkContext.scala:2672)
at org.apache.spark.sql.SparkSession$Builder.$anonfun$getOrCreate$2(SparkSession.scala:945)
at scala.Option.getOrElse(Option.scala:121)
at org.apache.spark.sql.SparkSession$Builder.getOrCreate(SparkSession.scala:939)
[...]
at com.mymainpackage.Main.main(Main.java:157)
I have finally been able to figure this one out.
The root cause was that an older version of hadoop-core was being pulled in (1.2.1 instead of 2.6.5), which does in fact not have the Configuration.getPassword() method. I found this out after setting up a test project where the SparkContext was initialized correctly and then checking the source jars of the two Configuration classes in the two projects (using Configuration.class.getProtectionDomain().getCodeSource().getLocation().getPath()).
After forcing version 2.6.5 using Maven's dependency management and after manually deleting the older 1.2.1 jar from the local Maven repo, it work fine.
The only thing that I still don't understand is why the hadoop-core was not showing up in the Maven dependency tree. Otherwise, I would have found sooner (probably).

Tomcat seems to reference an older version of a dependency (spring-web)

I'm using IntelliJ with the IvyIdea plugin. I added spring as dependency, rev 4.3.16 (the one my team uses).
After successfully building the project (which is a rest api), I tried to deploy it as an exploded war using tomcat 8.5.12 (again, the one my team is using).
When the deployment is running I get this exception:
NoSuchMethodException: org.springframework.web.accept.ContentNegotiationManager.getStrategy(Ljava/lang/Class;)
Reading the official documentation, I can see that the getStrategy method was introduced on Spring 4.3 so not sure what I'm doing wrong. I've tried cleaning the Ivy cache but it didn't help.
Any help would be appreciated.

Maven subdependency conflict at runtime with Twilio

Getting a class not found error at runtime due to maven sub dependency issue:
I am working on integrating twilio sdk ( com.twilio.sdk:twilio:7.35.0 ) into a multi module maven(3.x)/java(java8) project.
I firstly added the twilio maven dependency to the corresponding module
And I am getting a class not found exception at runtime on org.apache.http.conn.HttpClientConnectionManager.
I looked into it and found out that this class is part of org.apache.httpcomponents:httpclient (which is a subdependency in the twilio sdk ) and that an earlier version of this dependency is in my project.
And this earlier version does not have the HttpClientConnectionManager class.
So from this point, I tried to exclude the old version of the dependency with exclude tag first then with maven enforcer plugin and in the same time importing the dependency directly but nothing worked.
I tried to import the dependency in the parent pom and in the other modules that are using my twilio module as well.
I am using twilio 7.35 which uses org.apache.httpcomponents:4.5.6 but in my multi-module project I am using org.apache.cassandra:cassandra-thrift:3.0.0 which is using thrift:0.9.2 which contains the old version of httpclient(4.2.5).
The latest version of this cassandra module does not support the latest version of httpClient, so I need to make sure this httpclient older dependency does not mess up the twilio one.
I also analysed the output of mvn dependency:tree -Dverbose and it seems that the 4.5.6 is getting picked up correclty. And when I tried adding it to the parent module or the calling module, I can see that the old version is getting overwritten by the twilio one but it does not solve my issue.
I am starting to wonder if it is even possible to have two versions of the dependencies in the same maven project.
It sounds like you are experiencing something similar to a related question dealing with Jar Hell: Jar hell: how to use a classloader to replace one jar library version with another at runtime
In this case you need to use a separate classloader from the default one in your project. Perhaps you could use the URL Classloader and load some or all of your newer dependencies from the filesystem.

How to solve a JAR conflict in Tomcat web app required for a plugin that has a dependency on a class already in WEB-INF/lib?

I built a plugin for a web app that uses tomcat.
The plugin is registered as a servlet bean.
Now I want to use rabbitmq with the latest amqp client lib. Which has a dependency on classes in slf4j-api-1.7.25.jar.
Unfortunately the web app has also a dependency on slf4j but an older version.
So adding the the new jar file crashes the web app.
Is there anything to rescue? I have two dependencies out of my control.
No.
Use an older version of the amqp client which has the dependencies you like.
Then at your leisure upgrade the web app to the version of slf4j pulled in by the client. Might even be due diligence.

JarJar'ed artefact and Maven deploy process

I am currently developing an SDK targetting both servers and Android devices.
My deliverable JAR is JarJar'ed, thus preventing any dependency leaks from happening in client apps (using maven-jarjar-plugin).
However, there is one issue that puzzles me. A standard Maven deploy will ship sources, POM and other things. The problem is that any Maven-compatible build tool (e.g.: Gradle) will first resolve our SDK according to the deployed POM, thus triggering the pointless downloads of my SDK dependencies (remember: they are JarJar'ed in the final JAR!).
How can I deploy my SDK so that any build tool will understand there is nothing but the SDK to download?
That strange, I'm surprised if the jar jar plugin doesn't support it natively. You may give a try to the shade plugin which is also allowing to relocate classes and for sure it creates and deployed a modified pom for your artifact that won't expose your embedded dependencies to others projects using yours.
See :
http://maven.apache.org/plugins/maven-shade-plugin/examples/class-relocation.html
http://maven.apache.org/plugins/maven-shade-plugin/shade-mojo.html#createDependencyReducedPom
cheers

Categories