Jackson 2.x annotations not picking up in a separate jar project - java

I have an interesting problem: Jackson 2.x annotations are not picked up in a separate Maven module project on Weblogic 12.1.3 with Jersey 2.17 (JAX-RS 2.0).
My project structure is this:
project EAR
--> domain JAR: contains JPA & Jackson2 annotated POJOs
--> WAR: contains REST API
If I put Jackson-annotated POJOs inside WAR, then Jackson annotations got picked up, and correct JSON output is generated.
It might be a possible duplicate question, regarding this: Jackson 2 annotations ignored in EJB Jar with JBoss (6.2.0 GA), but I couldn't make it work on Weblogic.
It doesn't work in a separate (domain) jar.
I've tried different Maven solutions (skinny war, WL-specific classloading), but nothing seems to be working.
Here are the relevant details that you might find interesting...
My domain-JAR pom.xml includes the following:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<scope>provided</scope>
</dependency>
My WAR contains the following dependencies:
<dependency>
<groupId>hu.dboros</groupId>
<artifactId>restaurant-manager-domain</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
My EAR contains just the war, as dependency:
<dependency>
<groupId>hu.dboros</groupId>
<artifactId>restaurant-manager-backend-war</artifactId>
<version>${project.version}</version>
<type>war</type>
</dependency>
And my root pom contains the following dependencies (according to the Jersey 2.x guide):
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.bundles</groupId>
<artifactId>jaxrs-ri</artifactId>
<version>${jersey.version}</version>
<scope>provided</scope>
</dependency>

Related

Use Provided jax-rs 2.0 and Jersey 2.1x in Weblogic 12c (12.2.1.3)

I need to implement a rest service call in my WEB application. According to Oracle, Weblogic is supported and does not need to register (deploy) jax-rs, so I would like to use these Server libraries. I made a simple class by calling a service (get). I configured the dependencies in the project and deployed it on Weblogic. However, when deploying, the following error appears: java.lang.ClassCastException: Cannot cast org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider to org.glassfish.jersey.server.spi.ComponentProvider
Note: It worked using this link below (deploying the jar on the server) But I want to use the native libraries on Weblogic. Could someone help me please?
https://docs.oracle.com/middleware/1213/wls/RESTF/use-jersey20-ri.htm#RESTF297
Code example (Java)
String host = "https://swapi.dev/api/people/2/";
Client client = ClientBuilder.newBuilder().build();
WebTarget webTarget = client.target(host);
Builder builder = webTarget.request(MediaType.APPLICATION_JSON);
String result = builder.get(String.class);
pom.xml
<properties>
<primefaces.version>3.5.RC1</primefaces.version>
<jersey.version>2.21.1</jersey.version>
<jaxrs.version>2.0</jaxrs.version>
</properties>
<!-- JAX-RS -->
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>${jaxrs.version}</version>
<scope>provided</scope>
</dependency>
<!-- Jersey 2.21.1 -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>${jersey.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.4.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
weblogic.xml
<wls:weblogic-version>12.2.1.3</wls:weblogic-version>
<wls:context-root>RecebimentoMercadoriaWEB</wls:context-root>
<wls:library-ref>
<wls:library-name>jsf</wls:library-name>
</wls:library-ref>
<wls:container-descriptor>
<wls:prefer-web-inf-classes>true</wls:prefer-web-inf-classes>
</wls:container-descriptor>
<wls:session-descriptor>
<wls:cookie-name>CookieRecebimentoMercadoria</wls:cookie-name>
</wls:session-descriptor>
<wls:container-descriptor>
<wls:prefer-application-packages>
<wls:package-name>javax.faces.*</wls:package-name>
<wls:package-name>com.sun.faces.*</wls:package-name>
<wls:package-name>com.sun.facelets.*</wls:package-name>
<wls:package-name>com.bea.faces.*</wls:package-name>
</wls:prefer-application-packages>
<wls:prefer-application-resources>
<wls:resource-name>javax.faces.*</wls:resource-name>
<wls:resource-name>com.sun.faces.*</wls:resource-name>
<wls:resource-name>com.sun.facelets.*</wls:resource-name>
<wls:resource-name>com.bea.faces.*</wls:resource-name>
<wls:resource-name>META-INF/services/javax.servlet.ServletContainerInitializer</wls:resource-name>
<wls:resource-name>META-INF/services/com.sun.faces.spi.FacesConfigResourceProvider</wls:resource-name>
</wls:prefer-application-resources>
</wls:container-descriptor>
On Weblogic 12.2.1.3 yo do not need to execute the procedure described by the link you have pointed, I mean the link below .
https://docs.oracle.com/middleware/1213/wls/RESTF/use-jersey20-ri.htm#RESTF297
This is because that link belongs to Oracle Weblogic 12.1.3 and there are several differences between Weblogic 12.1.3.0 and Weblogic 12.2.1.3.
Furthermore, this document for Oracle Weblogic 12.2.1.3 states.
Note:
Jersey 2.x (JAX-RS 2.0 RI) support is provided by default in this
release of WebLogic Server. Registration as a shared library is no
longer required.
This means, when it comes to Weblogic 12.2.1.3 Jersey libraries are in place and ready to be used. Thus, your application should be able to use them.
However, I think server libraries are getting troubles with the libraries you are using within your pom.xml file.
Furthermore Oracle Weblogic 12.2.1.3 provides jersey 2.22.4
I have also used wls-cat in one of my servers to know, which library is loading the class org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider and I have found the library in $ORACLE_HOME/oracle_common/modules/org.glassfish.jersey.ext.cdi.jersey-cdi1x.jar, which means it is loaded by Weblogic as is stated on above documentation.
Furthermore, after running wls-cat I can see this:
org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider implements org.glassfish.jersey.server.spi.ComponentProvider
Thus, cast should not be an issue, which means there is a class loading problem that most probably is caused by libraries included in your application.
You can see the results of wls-cat executed on my server on below picture
You can use wls-cat to see which file (a JAR library) is loading the conflicting class. In below post you will find information about how to use wls-cat to analyse class loading problems.
https://blog.sysco.no/class/loader/AnalysingClassLoadingConflicts/
The libraries were really conflicting. I removed these dependencies from pom.xml and it worked. Thanks for the tip.
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>${jersey.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.4.1</version>
<scope>provided</scope>
</dependency>

Apache HTTPClient dependency issue : POM

I'm having issue while using Apache HttpClient in my java application.
2019-02-11 07:09:18,270 ERROR [Call-Dequeue-Delegator] (HibernateUtil.java:275) - Building SessionFactory failed.
java.lang.NoClassDefFoundError: org/apache/http/client/methods/HttpRequestBase
at java.lang.Class.getDeclaredMethods0(Native Method)
It runs fine on my local machine but not on servers. Since it is a client application I'm not having details of server etc.
Following is my Code:
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(20)
.setConnectionRequestTimeout(30).build();
// Creating client with request configuration(timeouts) & disabling redirect following
CloseableHttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(config).disableRedirectHandling().build();
String endpoint = this.getSOAPEndPoint();
String queryParamWithSurveyData = addDataToQueryParam(endpoint, customRequestModel);
endpoint += queryParamWithSurveyData;
HttpRequestBase httpRequestWithoutBody = null; // Failing at this
In the above code it's failing at the last line & I'm surprised why not on first one since both (RequestConfig & HttpRequestBase) are imported from HTTPClient.jar
Following is my POM snippet
//Existing sample dependency
<dependency> //Existing sample dependency
<groupId>com.connectfirst.intelliqueue</groupId>
<artifactId>gson</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/lib/couchbase/gson-2.3.jar</systemPath>
<version>1</version>
</dependency>
// New dependencies added
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/lib/httpcore-4.4.11.jar</systemPath>
<version>1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/lib/httpclient-4.5.7.jar</systemPath>
<version>1</version>
</dependency>
I saw somewhere that HttpClient is dependent on some other JARs as well & therefore added the following dependencies as well but had no luck.
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/lib/httpcore-4.4.11.jar</systemPath>
<version>1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/lib/httpclient-4.5.7.jar</systemPath>
<version>1</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/lib/commons-codec-1.11.jar</systemPath>
<version>1</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/lib/commons-logging-1.2.jar</systemPath>
<version>1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>fluent-hc</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/lib/fluent-hc-4.5.7.jar</systemPath>
<version>1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient-cache</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/lib/httpclient-cache-4.5.7.jar</systemPath>
<version>1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient-osgi</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/lib/httpclient-osgi-4.5.7.jar</systemPath>
<version>1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient-win</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/lib/httpclient-win-4.5.7.jar</systemPath>
<version>1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/lib/httpmime-4.5.7.jar</systemPath>
<version>1</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/lib/jna-4.5.2.jar</systemPath>
<version>1</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/lib/jna-platform-4.5.2.jar</systemPath>
<version>1</version>
</dependency>
The JAR gets created successfully on my local with maven clean install.
Any lead would be helpful.
Thanks.
Why are you scoping to system? That would imply that the jars are on the classpath of the running application. If you switch that to compile, assuming you're packaging as a spring-boot JAR or WAR file, they will be included in the resultant artifact. Without that the application cannot find the dependencies you are working with.
The scope attribute dictates where dependencies should be placed on the classpath.
compile - the artifact is available for reference by the project code and should be bundled (ostensibly) with the resultant artifact (e.g. embedded in WAR under WEB-INF/lib or spring-boot as BOOT-INF/lib)
provided - the artifact is available for reference by the project source code but is not included in the resultant artifact (think JSP libraries in a web app, you want to defer to the container implementation).
runtime - the dependency classes are not available for direct reference by the project source code but is referenced at runtime (think JDBC driver, you don't specifically use that you load it, traditionally, by reflection using the name).
test - the dependency classes are available to sources in src/test/java (etc). IDEs are supposed to separate the references but not always the case (e.g. Eclipse). If you try to reference a test scoped dependency from src/main/java your code will not compile because the dependency is not available.
system - The artifact in this case is explicitly located by path and is expected to be available at runtime within the consuming application's classpath.
import - This is only supported within the dependencyManagement elements.
You can see the description from the official documentation.
Please make sure you are using correct java version on server.
Please note that as of 4.4, HttpClient requires Java 1.6 or newer. for httpClent after 4.4 version you need to use newer java versions (say java 11) .

Jackson 2.0 annotations in dependent jar ignored

We have a web application that used to be deployed as a war in Jboss AS 7 . This webapp uses both reasteasy and jackson( 2.0 ) to serialize and deserealize data from a mongodb database. Some time ago we had to separate the webapp into 2 different maven modules , and API (jar) and WAR . all our POJOs were on the jar module . The problem is that all the jackson annotation became useless. They are just completely ignored .
More info
jboss-deployment-structure.xml :
<exclusions>
<module name="org.codehaus.jackson.jackson-core-asl"/>
<module name="org.codehaus.jackson.jackson-mapper-asl"/>
</exclusions>
POM (API)
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.0.0</version>
<scope>provided</scope>
</dependency>
POM(WAR)
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.0.0</version>
<scope>provided</scope>
</dependency>
I read that reasteasy modules and jackson modules could somehow conflict since resteasy could be using some old jackson version . How can i check this ? Or is this a problem of the jboss classloaders ? (Jackson 2 annotations ignored in EJB Jar with JBoss (6.2.0 GA))
#NokusFerreira, basically you are correct. I know this is an old question, but I hope this answer will help somebody.
Since you haven't told when problem occurs (during serialization in JAR or during deserialization in WAR). I'm guessing that during deserialization inside WAR module.
If yes, then your WAR is probably using resteasy-client and resteasy-jackson-provider, and here problem lies - because to work with Jackson 2.x RESTEasy needs a different module: resteasy-jackson2-provider (please note "2" suffix) instead of old resteasy-jackson-provider.
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson2-provider</artifactId>
<version>3.0.11.Final</version>
</dependency>
But unfortunatelly, resteasy-jackson2-provider is not bundled with JBoss 7.1.
So basically you have following options:
Migrate to a newer server (like WildFly).
Upgrade RESTEasy library on the JBoss.
Downgrade your code to be using Jackson 1.x
It is a common inconvenience in a JEE world, that libraries declared as your dependencies are provided by the application server (and may differ from ones that you are thinking you are using).
EDIT
Also this answer may be useful: How to make Resteasy 2.3.6 use Jackson 2.+

What Jersey dependency to add to avoid NoClassDefFoundError for jersey.repackaged.com.google.common.collect.Maps

I'm trying to run a a test that extends JerseyTest but when running it I'm getting a:
java.lang.NoClassDefFoundError: jersey/repackaged/com/google/common/collect/Maps
Any idea what dependency I'm missing? I've included the following jersey artifacts in my pom.xml and jersey.version is 2.5.1:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.jersey-test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
<version>1.18</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>2.6</version>
<scope>test</scope>
</dependency>
You'll need:
<dependency>
<groupId>org.glassfish.jersey.bundles.repackaged</groupId>
<artifactId>jersey-guava</artifactId>
<version>2.6</version>
</dependency>
From http://blog.dejavu.sk/2014/02/21/jersey-2-6-has-been-released-new-and-noteworthy/
Jersey, from versions 2.6 for JAX-RS 2.0 and 1.18.1 for JAX-RS 1.1, no longer transitively brings Guava and ASM libraries to your application. This means that even when we still use them internally you can use different versions of these libraries. Classes from both of these libraries has been repackaged, jersey.repackaged.com.google.common and jersey.repackaged.objectweb.asm respectively, and shrinked to lower the footprint. ASM 5 is now part of jersey-server core module and for Guava we’ve created a separate bundle module jersey-guava as this dependency is widely used in multiple Jersey modules.
You're using the Jersey 2.6 jersey-test-framework-provider-grizzly2.

NoClassDefFoundError. How to set dependencies and deploy a java app?

My Java app requires org.objectweb.asm library. I specified 'asm' dependency in pom. That deploys the library together with the app. Still the app throws exception NoClassDefFoundError: org/objectweb/asm/ClassVisitor.
java.lang.NoClassDefFoundError: org/objectweb/asm/ClassVisitor
at com.sun.jersey.api.core.PackagesResourceConfig.init(PackagesResourceConfig.java:112)
at com.sun.jersey.api.core.PackagesResourceConfig.<init>(PackagesResourceConfig.java:78)
... many more
How can I fix the problem?
Details:
I am using Glassfish 2.1.1. The app requires jersey 1.1.4, jersey requires asm 3.1. I assume 1.1.4 version is required by glassfish 2.1.1
If I run Glassfish updatetool and install Jersey on the server then my app loads and runs with no problems. My client doesn't have Jersey installed on their server and they can not use updatetool.
Glassfish 2.1.1 updatetool installs jersey 1.1.4 and asm-3.1.jar in glassfish/lib directory.
When jersey is uninstalled, updatetool removes asm too.
If I include jersey and asm as dependencies and deploy my war file then jersey and asm jars go into local location, e.g. glassfish/domains/domain1/applications/j2ee-modules/MYAPPNAME/WEB-INF/lib/asm-3.1.jar.
Glassfish updatetool puts asm into lib folder: glassfish/lib directory the app start deploying and working correctly.
Here is my maven pom file dependency section:
<dependencies>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>
<version>1.1.4</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.jersey-test-framework</groupId>
<artifactId>jersey-test-framework-grizzly2</artifactId>
<version>1.17.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>1.0.0.Final</version>
<scope>provided</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
I had a conflict with an older jersey library stored in glassfish/lib folder:
glassfish/lib/jersey-bundle-1.0.3.1.jar
It was loaded and used instead of jars placed in a folder local to the app:
glassfish/domains/domain1/applications/j2ee-modules/MYAPPNAME/WEB-INF/lib/
Jersey jar from 'lib' folder was looking for 'asm' library in the same 'lib' folder, hence my locally placed asm-3.1.jar was never found.
I expected that 'local' jars were loaded first. Appeared that the search order is different. Is that really the case? Please tell me if I am wrong.
I found the problem by verifying which library is used with the following code:
logger.debug(PackagesResourceConfig.class.getResource("PackagesResourceConfig.class"));
Note PackagesResourceConfig class listed in the exception thrown.
Hopefully this answer will help someone else to save their time.
Try something like that in your pom:
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.3.1</version>
</dependency>

Categories