Unsupported Media Type Jersey - json

I am using Maven and Jersey on Tomcat7 to build a web server, but I keep getting a 415 response. My request is made using Postman and Advanced Rest Client
My stubbed method:
#POST
#Path("/createuser")
#Consumes(MediaType.APPLICATION_JSON)
public Response createUser(UserInformation user){
return Response.ok().build();
}
Custom class:
package efile.models;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
#JsonInclude(Include.NON_NULL)
public class UserInformation {
private String id;
private String username;
private String password;
private String firstName;
private String lastName;
private String emailAddress;
/* getters and setters */
}
Request:
{myhost}/createuser
Headers:
accept: application/json
content-type: application/json
Request body:
{
"id":"1234567",
"userName":"qwer",
"password":"zxcv",
"firstName":"jasdfme",
"lastName":"qwetad",
"emailAddress": "qwet#gf4elk.com"
}
My dependencies:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.25</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.17</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>
<version>1.17</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.17</version>
</dependency>
<dependency>
<groupId>com.dropbox.core</groupId>
<artifactId>dropbox-core-sdk</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>org.jvnet.mimepull</groupId>
<artifactId>mimepull</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>1.17</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.2.0</version>
</dependency>
Thanks.

On my side it was because I forgot to add
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.18</version>
</dependency>
after
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.18</version>
</dependency>
No warnings/errors at compilation but 415 Unsuported Media Type at runtime trying to consum JSON on Jersey 2.18 running on AppEngine
Hope it helps

If you are sending the 'Accept' header, you may also need to add the #Produces(MediaType.APPLICATION_JSON) annotation to your method, or, remove the Accept header from the request if you are not expecting a response body.
Edit:
Ok... After a bit of experimentation, I believe I have been able to reproduce your problem and find a solution.
I see from your pom file that you are using Jersey 1.17. I reproduced your problem using Jersey 1.18, but I suspect it is equally valid for 1.17. It appears that Jersey does not come with Jackson support built in, but Jackson must be installed as a provider. I've always used it with containers like Glassfish where the providers come pre-configured.
I was not able to make Jersey 1.18 work with the latest Jackson 2 libraries (under the com.fasterxml.jackson groupId) that you were pulling in with your pom.xml, but I was able to get it working with the older Jackson libraries when the groupId was still org.codehaus.jackson. It appears that Jersey 1.18 uses a class called com.sun.jersey.json.impl.provider.entity.JacksonProviderProxy which looks specifically for a Jackson implementation in org.codehaus.jackson... So you might not be able to make the newer versions of Jackson work without upgrading to a newer version of Jersey.
Firstly, I added the XmlRootElement annotation to the UserInformation class. Jax-RS will serialize and deserialize JAXB objects and this annotation marks this class as a JaxB object. This required an additional dependency in the pom on the jaxb-api:
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
</dependency>
Next, I removed all of the Jersey dependencies from your pom.xml file, and added a dependency on the jersey-server to give access to the necessary JaxRS annotations:
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.18</version>
<scope>provided</scope>
</dependency>
I then took a clean installation of Tomcat 7.0.52, and added the following jars to the CATALINA_HOME/lib directory:
asm-3.3.1.jar (Byte code manipulation used by Jackson)
jacksore-core-asl-1.9.13.jar (Includes the Jackson JSON Provider)
jersey-bundle-1.18.jar (The Jersey Implementation)
I found it necessary to add these jars to the Tomcat lib folder rather than include them in the project WAR file. I don't work with Tomcat much, so I don't recall the rules about exactly when it is necessary to place jars in the Tomcat lib directory vs. including them in the WAR file.
Following all of those steps I was able to go from getting the 415 Media Unsupported error to a 200 OK on the POST.
I hope this helps.

I was able to resolve the issue after modifying the dependencies in the pom.xml. I updated the jersey dependencies to 1.18.1 and added the fasterxml json provider dependency:
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.2.1</version>
</dependency>
My guess is that it was just the json-provider dependency that resolved the issue.

Related

Error:org.apache.commons.logging.LogFactoryjava.lang.NoClassDefFoundError for application build with micronaut-bom1.2.10, graal19.2.1 & aws-sdk2.10.56

Created an application using micronaut bom 1.2.10 version, along with software.amazon.awssdk:lambda:2.10.56 & software.amazon.awssdk:s3:2.10.56 dependencies which had functionality to retrieve data from s3 storage and used graal 19.2.1 to create a native image.
The native image is successfully created but when i try to access the endpoint it fails for below exception:
failed: org.apache.commons.logging.LogFactoryjava.lang.NoClassDefFoundError: org.apache.commons.logging.LogFactory
and series of exceptions with specifically while creating S3 client.
The exception also had failure at below point:
failed: Could not initialize class software.amazon.awssdk.http.apache.internal.conn.SdkTlsSocketFactoryjava.lang.NoClassDefFoundError: Could not initialize class software.amazon.awssdk.http.apache.internal.conn.SdkTlsSocketFactory
Code for S3Client :
S3Client s3Client = S3Client.builder().region(getRegion()).build();
build-native-image.sh
${GRAALVM_HOME}/bin/native-image --no-server -cp example-function-*-all.jar
-H:IncludeResources="git.properties"
-H:IncludeResources="logback.xml"
-H:IncludeResources="application.properties" \
So this issue was resolved by adding below configuration in build.gradle:
allprojects {
configurations {
all {
exclude(group = "commons-logging")
}
}
}
and in the dependencies added:
compile group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.7.30'
I hope this helps.
I faced the same issue, when running tests, with the exact same NoClassDefFoundError but when using AWS sts and secretsmanager libraries. I could actually get it to work by just including the jcl-over-slf4j dependency, while the error happened when using the slf4j-api dependency. I did not need to exclude commons-logging. Snippet of dependency in maven pom.xml that worked:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bom</artifactId>
<version>2.17.89</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>secretsmanager</artifactId>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>sts</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</dependency>
</dependencies>

Liferay 7 & JUnit : Mock Local Custom Local Service Util

I'm trying to mock with powermockito my custom local service util, but i always get an error.
#RunWith(PowerMockRunner.class)
#PrepareForTest({ServiceSubscriptionLocalServiceUtil.class})
public class CStreamTest {
#Before
public void setUp() throws NoSuchFieldException, IllegalAccessException {
.........
mockStatic(ServiceSubscriptionLocalServiceUtil.class);
.........
}
}
and i'm getting the following error :
java.lang.ExceptionInInitializerError
at sun.reflect.GeneratedSerializationConstructorAccessor4.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:48)
at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
at org.mockito.internal.creation.instance.ObjenesisInstantiator.newInstance(ObjenesisInstantiator.java:19)
at org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.createMock(SubclassByteBuddyMockMaker.java:47)
at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createMock(ByteBuddyMockMaker.java:25)
at org.powermock.api.mockito.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:41)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:35)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:62)
at org.mockito.Mockito.mock(Mockito.java:1896)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMethodInvocationControl(DefaultMockCreator.java:108)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.doCreateMock(DefaultMockCreator.java:61)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMock(DefaultMockCreator.java:53)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.mock(DefaultMockCreator.java:40)
at org.powermock.api.mockito.PowerMockito.mockStatic(PowerMockito.java:62)
at com.e.c.stream.impl.test.CStreamTest.setUp(CStreamTest.java:50)
i add some parts of my pom.xml :
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.12.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.24.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
Any ideas ?
Thanks
Liferay's *LocalServiceUtil classes contain a bunch of static methods that just simplify the lookup of an actual service implementation. Given that you state you're on Liferay 7, you should just utilize the services themselves and rely on #Reference dependency management and injection in the code that uses them. This way you just need to mock a regular interface that is not loaded with some default implementation and lookup.
Another option is to test the implementation - and write tests for the code "above" the service, as well as its implementation. It's typically hard to write UI-layer code, e.g. portlets, in a test-driven fashion, where mocking isn't heavily dependent on the implementation of the service and the calling classes.
Normally services utility classes created by Service builder do not have a no arg constructor, not even a constructor for that matter.
But if you check the log you will see and this is your issue:
New instance of the class is created inside PowerMock.
java.lang.ExceptionInInitializerError at sun.reflect.GeneratedSerializationConstructorAccessor4.newInstance(Unknown Source)
After trying to create an instance for: ObjenesisBase....
Even though it has not constructors, services utils normally initialize static members, like a ServiceTracker.
You could create a bummy service impl or your code could use the service reference instead of the util, you could mock that guy. Several options here, even mocking methods that give you the service to give you a dummy service.
But in summary, you cannot just do:
mockStatic(ServiceSubscriptionLocalServiceUtil.class);
As this will create an instance, and that instance has static members that need to be initialized.

Migration issue from Junit 4 to Junit 5

I am migrating my codebase from junit4 to junit5.I have used mockito in my testcase.Below are the different version that i am using for the dependency.
<junit.jupiter.version>5.2.0</junit.jupiter.version>
<junit.platform.version>1.2.0</junit.platform.version>
<org.mockito.version>1.10.19</org.mockito.version>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.19.0</version>
<scope>test</scope>
</dependency>
I have used the annotation #RunWith(MockitoJUnitRunner.class) to run my mockito code.Replaced the same with #ExtendWith(MockitoExtension.class)
But when i run the test case i get the below error. Any suggestion to solve this issue. I suspect is there any dependency version issue which is causing this problem.
java.lang.NoClassDefFoundError: org/mockito/quality/Strictness
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
at java.lang.Class.getConstructor0(Class.java:3075)
at java.lang.Class.getDeclaredConstructor(Class.java:2178)
at..
Thanks
-Sam
The JUnit5 MockitoExtension uses org.mockito.quality.Strictness so in order to use MockitoExtension you'll need to use a version of mockito-core which contains org.mockito.quality.Strictness. mockito-core:1.10.19 does not contain that class because that class was added in Mockito 2.x. So, in order to use MockitoExtension you'll need to use at least version 2.x of mockito-core.
The Mockito docs don't make this explicit but I suspect the expectation is that you'll use the same Mockito version for mockito-core and for mockito-junit-jupiter.
The following dependencies will allow you to use the JUnit5 MockitoExtension successfully:
<org.mockito.version>2.19.0</org.mockito.version>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${org.mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${org.mockito.version}</version>
<scope>test</scope>
</dependency>
I tried to use same version for mockito-junit-jupiter and mockito-core, but fails.
At last I init the mocks myself in #BeforeEach block.
#BeforeEach
private void setup() {
MockitoAnnotations.initMocks(this);
}
as a workaround.
Thanks for the response #glytching .With your input i was able to find the correct version dependency for me and it resolved my issue. Below is the version that i used to resolve the same.
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>1.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.22.0</version>
<scope>test</scope>
</dependency>
Also i needed mockito-core => version 2.22.0. But above mentioned mockito-junit-jupiter comes with mockito core dependency internally.So no need to add that dependency.

Jackson #JsonSerialize ignored in Jboss 7.1.1 if maven dependecy set to provided

I have Jax-rs endpoint deployed in WAR archive on JBoss 7.1.1.
In its JSON response I don't want my null field name to be included, so I put #JsonSerialize on it.
class MyResponse {
private Long id;
#JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
private String name;
private List<String> addresses;
// getters and setters
}
My pom.xml has the following
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>2.3.2.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>2.3.2.Final</version>
<scope>provided</scope>
</dependency>
When the scope for resteasy-jackson-provider is set to provided it ignores the annotation and returns null in JSON response. However when I remove the scope from maven dependency - it works.
From the page here https://docs.jboss.org/author/display/AS71/Implicit+module+dependencies+for+deployments it looks like JBoss should autoload this module if Jax-RS deployment found.
Now I don't know if this is a bug and if I should really include this dependency (NOT keeping it provided). Or maybe I'm doing something wrong there?
You need to make sure to create a JBoss Deployment Structure descriptor.
Since this is a Maven project I assume it would be under src/main/webapp/WEB-INF/jboss-deployment-structure.xml
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
<deployment>
<dependencies>
<module name="org.codehaus.jackson.jackson-core-asl" />
<module name="org.codehaus.jackson.jackson-mapper-asl" />
</dependencies>
</deployment>
</jboss-deployment-structure>
This will allow the built-in support for RESTEasy and Jackson to work correctly in JBoss 7.1.x or JBoss EAP 6.x. Without this descriptor RESTEasy will use the Jettison provider.

JSON with JAXB using Maven

I am using Jersey (with Jetty) and Maven to implement a RESTful service. I am trying to send a JSONObject using JAXB, I have followed some tutorials such as: http://jersey.java.net/nonav/documentation/1.7/user-guide.html#d4e919 and http://www.vogella.com/articles/REST/article.html
So I just have a simple bean that I want to send as a JSON Object. I have followed all the steps, but I am not able to send the JSON Object (although I do recieve the XML format correctly). I obtain the following exception: com.sun.jersey.api.MessageException: A message body writer for Java class de.vogella.jersey.jaxb.model.Todo, and Java type class de.vogella.jersey.jaxb.model.Todo, and MIME media type application/json was not found
I have tried different solutions that I found around, but nothing seems to work.
I am wondering if I must have any dependencies missing or I have to implement a ContextResolver (although any tutorials use them for easy objects like these ones).
These are the dependencies that I have:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- Jersey -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.11</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.11</version>
</dependency>
<!-- Json -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.11</version>
</dependency>
<!-- Jetty -->
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>6.1.26</version>
</dependency>
</dependencies>
Thank you very much
I have found the missing dependency:
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.0.0</version>
<scope>compile</scope>
</dependency>
And I had to add a repository as well to avoid missing archetypes errors:
<repositories>
<repository>
<id>EclipseLink Repo</id>
<url>http://www.eclipse.org/downloads/download.php?r=1&nf=1&file=/rt/eclipselink/maven.repo</url>
</repository>
</repositories>