Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jersey-dev] [External] : Jersey servlet failing to intercept the api calls
  • From: Jan Supol <jan.supol@xxxxxxxxxx>
  • Date: Thu, 20 May 2021 10:14:55 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Kozt+uP1prK0jwjB7SDgU4sZMkvRmoKy7AL5y/yAldw=; b=Yf0B/tQePi2Yeuc8W1Z1nNwPkMy7h3DRhU06l1nUZzf1xDNvi1wEn5cz+Od/t3O7PHr5asw/7db4yPu1zN4O9SGqVatS+pYym0VhY6wnN1X4EmYAupD8ifREuK9n1Xn4tUL7joObQAj7OMJL0fNjOE3ZABZ8IWEtuixczQV/ea93h5iqxNrEjFD1onkRd6wNkc/tJV7xfofxog1tj0VJSFjenP73Uc62jVO6Isdm3+ciBifGYBGSjLhNlxLoaOTPtAhkXpSc9xtrbkYAptFPvres7riW/9vOCLvlU5JZguy1oG18OGJd79KSGQSeCzyBUscjBivbXNfkscqlUVpBRg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ey/KhbmlkiAHhExoUsbS/XkAKX/C79VD+6M1npEPg+ZaRwWEPYj0xpsy17kjUVSyRXefGc2s07wQMpEflAJHyEcnphrnPSspZBRIdnf8zQ7S/8JBvwShL9LjdVLDOhig02G4QPHB9m0JfoYRvv3uV6yf9Xn+5jL+O9mavnWuMs739j0/tt+Vg0venF/LGCJx4BoKL6dFfZqO6OXyKCCbBaqLP8YuqDX8W5C8+hYH9ZKKO3h107CIjBf2Fir+iyJchmZ8mUWCXdwi5ct5rND+LEdM/ENPjwlcSZlSziYfET/21mwhGsjQzgJHXWNxWgSylTxnR9S93ULLG0cTzzQACg==
  • Delivered-to: jersey-dev@xxxxxxxxxxx
  • List-archive: <https://www.eclipse.org/mailman/private/jersey-dev/>
  • List-help: <mailto:jersey-dev-request@eclipse.org?subject=help>
  • List-subscribe: <https://www.eclipse.org/mailman/listinfo/jersey-dev>, <mailto:jersey-dev-request@eclipse.org?subject=subscribe>
  • List-unsubscribe: <https://www.eclipse.org/mailman/options/jersey-dev>, <mailto:jersey-dev-request@eclipse.org?subject=unsubscribe>
  • Thread-index: AQHXTOzaXl4eAAlAxkqYMDvROAniWqrsJrHa
  • Thread-topic: [External] : [jersey-dev] Jersey servlet failing to intercept the api calls

Hi,
The message 
"org.glassfish.jersey.server.model.ModelValidationException: Validation of the application resource model has failed during application initialization."
tells you the resource class is not understood by Jersey. I assume it is because you use the spring @RequestBody annotation instead of JAX-RS @Context annotation. I am not sure you would be able to inject the Jetty-specific Request, though.
-- Jan

From: jersey-dev <jersey-dev-bounces@xxxxxxxxxxx> on behalf of Aniruddha Tekade via jersey-dev <jersey-dev@xxxxxxxxxxx>
Sent: Wednesday, May 19, 2021 10:23 PM
To: JETTY user mailing list <jetty-users@xxxxxxxxxxx>
Cc: Aniruddha Tekade <atekade@xxxxxxxxxxxx>; jersey-dev@xxxxxxxxxxx <jersey-dev@xxxxxxxxxxx>
Subject: [External] : [jersey-dev] Jersey servlet failing to intercept the api calls
 
Hello Community,

I have been stuck at this issue for a long time now and need help in identifying what am I doing wrong. 
I have Jetty 11 and Jersey 3.0.2 and Swagger-core 2.1.9. I am wondering if any of the following are wrong in my project:
  1. Jetty & Jersey integration
  2. Dependencies w.r.to Jetty and Jersey
  3. Annotations of API
My control flow is as follows:
  1. Created jetty server that has 128 queue size
  2. Created a jetty servlet holder
  3. Added Jersey servlet so intercept / scan all my API paths
  4. I use Jakarta namespace for this project (you can find in the bottommost gradle for the dependencies )
But when I run the server with the above setting, I get:
Caused by: org.glassfish.jersey.server.model.ModelValidationException: Validation of the application resource model has failed during application initialization.

However, all my API calls are accessible without jersey or swagger servlet added and I confirmed this by exercising them using python script and also using postman. Now that I want to generate a swagger.json or openapi.yaml for all my apis, I try to scan using jersey model as follows:

// Setup API resources
ServletHolder jersey = servletContextHandler.addServlet(ServletContainer.class, "/api/*");
jersey.setInitOrder(1);
jersey.setInitParameter("jersey.config.server.provider.packages", "com.cloudian.hfs.handlers;io.swagger.v3.jaxrs2.integration.resources");

Where com.cloudian.hfs.handlers contain all resource classes and apis. What am I doing wrong? For detailed code: 

Jersy and Jetty integration:

import com.cloudian.hfs.handlers.*;
import io.swagger.v3.jaxrs2.integration.OpenApiServlet;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.glassfish.jersey.servlet.ServletContainer;
import java.util.logging.Level;
import java.util.logging.Logger;

public class StartHFS {

    public static void main(String[] args) throws Exception {
        System.out.println("StartHFS");

        // Create and configure a ThreadPool.
        QueuedThreadPool threadPool = new QueuedThreadPool();
        threadPool.setName("server");

        // Create a Server instance.
        Server server = new Server(threadPool);

        // HTTP configuration and connection factory.
        HttpConfiguration httpConfig = new HttpConfiguration();
        HttpConnectionFactory http11 = new HttpConnectionFactory(httpConfig);

        // Create a ServerConnector to accept connections from clients.
        ServerConnector connector = new ServerConnector(server, 1, 1, http11);
        connector.setPort(8080);
        connector.setHost("0.0.0.0");
        connector.setAcceptQueueSize(128);
        server.addConnector(connector);

        addHandlers(server);

        // Start the Server so it starts accepting connections from clients.
        try {
            server.start();
            server.join();
        } catch (Exception ex) {
            Logger.getLogger(StartHFS.class.getName()).log(Level.SEVERE, "Fail to start HFS Server", ex);
        } finally {
            server.destroy();
        }

        System.out.println("StartHFS DONE");
    }

static void addHandlers(final Server server) throws Exception {
        ContextHandlerCollection contexts = new ContextHandlerCollection();
        server.setHandler(contexts);

        ContextHandler featureStoreHandler = new ContextHandler("/featurestore");
        featureStoreHandler.setHandler(new FeatureStoreHandler());
        contexts.addHandler(featureStoreHandler);

        // Setup Jetty Servlet
        ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
        servletContextHandler.setContextPath("/");
        contexts.addHandler(servletContextHandler);

        // Setup API resources
        ServletHolder jersey = servletContextHandler.addServlet(ServletContainer.class, "/api/*");
        jersey.setInitOrder(1);
        jersey.setInitParameter("jersey.config.server.provider.packages", "com.cloudian.hfs.handlers;io.swagger.v3.jaxrs2.integration.resources");


        // Expose API definition independently into yaml/json
        ServletHolder openApi = servletContextHandler.addServlet(OpenApiServlet.class, "/openapi/*");
        openApi.setInitOrder(2);
        openApi.setInitParameter("openApi.configuration.resourcePackages", "com.cloudian.handlers;io.swagger.sample.resource");
    }
}


Gradle Dependencies:

plugins {
    id 'java'
    id "io.swagger.core.v3.swagger-gradle-plugin" version "2.1.9"
}

group 'com.cloudian'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    // Basic Gradle dependencies
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'

    // Logging dependencies
    runtimeOnly 'org.slf4j:slf4j-api:1.7.7'
    runtimeOnly 'org.slf4j:slf4j-log4j12:1.7.7'

    // Jetty dependencies
    implementation 'org.eclipse.jetty:jetty-server:11.0.0'
    implementation 'org.eclipse.jetty:jetty-servlet:11.0.0'
    implementation 'org.eclipse.jetty:jetty-util:11.0.0'

    // Jersey dependencies
    implementation 'org.glassfish.jersey.containers:jersey-container-jetty-http:3.0.2'
    implementation 'org.glassfish.jersey.containers:jersey-container-servlet-core:3.0.2'
    //    implementation 'org.glassfish.jersey.core:jersey-server:3.0.2'
    implementation 'org.glassfish.jersey.media:jersey-media-json-binding:3.0.2'
    implementation 'org.glassfish.jersey.core:jersey-common:3.0.2'
    // Jetty and Jersey InjectionManagerFactory dependency [Required]
    implementation 'org.glassfish.jersey.inject:jersey-hk2:3.0.2'
    // Enable JAXBContext and WADL Jersey [Required]
    implementation 'org.glassfish.jaxb:jaxb-runtime:3.0.1'

    // Redis & Json dependencies
    implementation 'org.springframework.data:spring-data-redis:2.4.3'
    implementation 'redis.clients:jedis:3.3.0'
    implementation group: 'org.json', name: 'json', version: '20201115'

    // Swagger, Jakarta deps
    implementation 'org.apache.commons:commons-lang3:3.7'
    implementation 'io.swagger.core.v3:swagger-jaxrs2-jakarta:2.1.9'
    implementation 'jakarta.ws.rs:jakarta.ws.rs-api:3.0.0'
    implementation 'jakarta.servlet:jakarta.servlet-api:5.0.0'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
}

resolve {
    outputFileName = 'MyRestAPI'
    outputFormat = 'YAML'
    prettyPrint = 'TRUE'
    classpath = sourceSets.main.runtimeClasspath
    buildClasspath = classpath
    resourcePackages = ['io.test']
    outputDir = file('test')
}

test {
    useJUnitPlatform()
}

jar {
    manifest {
        attributes "Main-Class": "com.cloudian.hfs.StartHFS"
    }

    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

Annotation of my APIs:
@Path("/featurestore/")
@Produces({"application/json", "application/xml"})
public class FeatureStoreHandler extends AbstractHandler {

    // Some final CONSTANTS for api implementation

    @Override
    public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException {}

    @POST
    @Path("/create")
    @Consumes("application/json")
    public void createFeatureGroup(@RequestBody Request jettyRequest, @RequestBody HttpServletRequest request, HttpServletResponse response) throws IOException, JSONException, JedisException {}

    @DELETE
    @Path("/delete")
    @Consumes("application/json")
    public void deleteFeatureGroup(@RequestBody Request jettyRequest, @RequestBody HttpServletRequest request, HttpServletResponse response) throws IOException, JedisException, JSONException {}

    @GET
    @Path("/describe")
    public void describeFeatureGroup(@RequestBody Request jettyRequest, @RequestBody HttpServletRequest request, HttpServletResponse response) throws IOException, JedisException, JSONException {}
}

Best,
Aniruddha
========

Back to the top