0

For days I am trying to get Glassfish 4.1.1 and Jersey working together. The tricky part is when there is communication via JSON.

I tried many solutions to get JSON data transfer working. Alas, still not working.

Glassfish and Jersey are 'standards', so I guess there is a standard way to combine these two? What is the correct way of configuring JSON?

Whenever I am starting to work with JSON, I get all kinds of errors. The last errors I get:

     2016-11-25T15:59:52.070+0100|Warning: StandardWrapperValve[Jersey Web Application]: Servlet.service() for servlet Jersey Web Application threw exception
java.lang.ClassNotFoundException: javax.xml.parsers.ParserConfigurationException not found by org.eclipse.persistence.moxy [228]
    at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1532)
    at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
etc, etc. 

The maven dependencies are:

http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>nl.xyz</groupId>
<artifactId>GlassfishJerseyJson</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>GlassfishJerseyJson</name>

<build>
    <finalName>GlassfishJerseyJson</finalName>
    <plugins>
            <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.1.1</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
                <!-- <webXml>src\main\webapp\WEB-INF\web.xml</webXml> -->
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.glassfish.maven.plugin</groupId>
            <artifactId>maven-glassfish-plugin</artifactId>
            <version>2.1</version>
            <configuration>
                <glassfishDirectory>${local.glassfish.home}</glassfishDirectory>
                <user>admin</user>
                <passwordFile>${local.glassfish.passfile}</passwordFile>
                <domain>
                    <name>domain1</name>
                    <httpPort>8080</httpPort>
                    <adminPort>4848</adminPort>
                </domain>
                <components>
                    <component>
                        <name>${project.artifactId}</name>
                        <artifact>target/${project.build.finalName}.war</artifact>
                    </component>
                </components>
                <debug>true</debug>
                <terse>false</terse>
                <echo>true</echo>
            </configuration>
        </plugin>
    </plugins>
</build>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.glassfish.jersey</groupId>
                <artifactId>jersey-bom</artifactId>
                <version>${jersey.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>javax</groupId> 
            <artifactId>javaee-web-api</artifactId> 
            <version>7.0</version> 
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet-core</artifactId> 
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.jaxrs</groupId>
            <artifactId>jackson-jaxrs-json-provider</artifactId>
            <version>2.6.3</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.6.3</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>2.5.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>
    <properties>
        <jersey.version>2.24.1</jersey.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>

The JQuery call is:

function findResource() {
    $.ajax({
        type: 'GET',
        accepts: { json: "application/json, text/javascript" }, 
        dataType: "json",
        url: resourceURL, 
        success: function(data){
            alert( "Back from resource: name=" + data.name); 
        }, 
        error: function(jqXHR, textStatus, errorThrown){
            alert('Back from resource error: ' + textStatus + ' - Error: ' + errorThrown + " - Response: " + jqXHR.responseText);
        }
    });
}

Resource java file:

@Path("myresource")
public class MyResource {
     @GET
     @Produces( MediaType.APPLICATION_JSON)
     public Wine2 getIt() {
         Wine2 w = new Wine2();
         w.setId( 100);
         w.setCountry( "france");
         return w;
     }
} 

Configuration: option 1: web.xml (left the default first line out):

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>org.coenraets.cellar</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey Web Application</servlet-name>
        <url-pattern>/webapi/*</url-pattern>
    </servlet-mapping>
</web-app>

Configuration: option 2: MyApplication.java

import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;

public class MyApplication extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> s = new HashSet<Class<?>>();
        s.add( MyResource.class);
        s.add( WineResource.class);
        return s;
    }
}
halfer
  • 19,824
  • 17
  • 99
  • 186
tm1701
  • 7,307
  • 17
  • 79
  • 168

4 Answers4

3

Yesssss!!!! I found the complete answer.

The solution is by using the original (see above) maven libs ANd to change the following files in the GLASSFISH/modules folder to verion 2.5.0 (or similar):

  • org.eclipse.persistence.moxy.jar
  • org.eclipse.persistence.core.jar

The solution came via [this webpage][1] and similar sites.

In this post and others the org.eclipse.persistence.moxy.jar file in the $Glassfish/modules is replaced with the 2.5.0 version.

tm1701
  • 7,307
  • 17
  • 79
  • 168
2

Just use the following instead of your moxy dependency:

    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-json-provider</artifactId>
        <version>2.6.3</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.6.3</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.5.1</version>
        <scope>provided</scope>
    </dependency>

The libs are included in the standard Glassfish 4 installation, therefore the provided scope is sufficient.

And you should remove these dependencies:

<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.json</artifactId>
    <version>1.0.2</version>
</dependency>
<dependency> 
    <groupId>javax.json</groupId> 
    <artifactId>javax.json-api</artifactId> 
    <version>1.0</version> 
    <scope>provided</scope>
</dependency>

and

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-moxy</artifactId>
    <!-- <version>2.4.1</version>
    <scope>provided</scope> -->
</dependency>

You don't need them and most of the Jersey dependencies can be set to provided.

If you don't get it to work: I created a gist with an example project, it has only 4 files: pom.xml, web.xml, MyResource.class and Cow.class. This includes everything you need for a basic setup and it works on Glassfish 4 without any additional libs.

unwichtich
  • 13,712
  • 4
  • 53
  • 66
  • Try to find the usage of this class and remove it. – unwichtich Nov 25 '16 at 10:45
  • Where do you use these classes? You don't need them. – unwichtich Nov 25 '16 at 11:58
  • How did you introduce them in the project? Just revert that. The code you are showing is not using these classes, therefore they should not be required to run the project. Do you have a Application.class which extends ResourceConfig? – unwichtich Nov 25 '16 at 12:34
  • Then you have a reference to moxy somewhere in your project...it is not used automatically. – unwichtich Nov 25 '16 at 14:46
  • I guess its comming from the dependency-management part in your pom.xml. You definitely don't need that, remove it. – unwichtich Nov 25 '16 at 15:13
  • Thank you very much. Can I test it from the browser with http://localhost:8080//minirest/webapi/myresource? Then it gives 404. Will write an JQeury with json datatype. The project is called 'minirest'. I had to change the project facets: contains 1.7, jsf2.2 (had to), Dynamic web module 2.5. I have Glassfish 4.1.1. – tm1701 Nov 25 '16 at 16:03
  • Yes, the URL is correct. Do you see in the Glassfish server.log that it is deployed successful? – unwichtich Nov 25 '16 at 17:24
  • In the gist furhter info is put. When we succeed in getting this working I will be glad to give you a bounty of +50. – tm1701 Nov 25 '16 at 17:52
0

Try to add in Library: Java EE7 API Library, JAX-RS, Jersey.

Matija P.
  • 1
  • 1
  • Can you please add the maven file or lib-dependencies? I have tried many variants already. The main thing is the JSON part. – tm1701 Nov 25 '16 at 09:01
  • For jax-rs and Jersey you have example : https://stackoverflow.com/questions/25612117/how-do-you-include-jax-rs-with-jersey-in-maven For Java EE7 API : https://mvnrepository.com/artifact/javax/javaee-api/7.0 – Matija P. Nov 25 '16 at 12:08
0

The solution for you can be to provide a custom JSON Provider your Jersey Application. It's definition will look like this:

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;

import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Produces(MediaType.APPLICATION_JSON)
public class CustomJsonProvider extends JacksonJaxbJsonProvider {

    private static final ObjectMapper MAPPER = new ObjectMapper();

    static {
        MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        MAPPER.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        MAPPER.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.DEFAULT);
        MAPPER.enable(SerializationFeature.INDENT_OUTPUT);
     }

    public CustomJsonProvider() {
        super();
        setMapper(MAPPER);
    }
}

Then a feature that will register your custom JSON Provider to the Jersey Application context:

import javax.ws.rs.core.Feature;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;

public class MarshallingFeature implements Feature {

    @Override
    public boolean configure(FeatureContext context) {
        context.register(CustomJsonProvider.class, MessageBodyReader.class, MessageBodyWriter.class);
        return true;
    }
}

Finally, register that feature in the Jersey Application class constructor:

import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;

@ApplicationPath("ws")
public class ApplicationConfig extends ResourceConfig {

    public ApplicationConfig() {

        register(MarshallingFeature.class);

        // register ressource classes
    }
}

And these are the dependencies you need to add to your Maven pom.xml:

    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.5.1</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.8.0</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.8.2</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-json-provider</artifactId>
        <version>2.8.6</version>
        <type>jar</type>
    </dependency>

Hope it helps.

Doudou G.
  • 29
  • 7