Hi,

ich habe eine Jersey webapplication, die verschiedene REST Schnittstellen via Plugins anbietet.

Meine bisherige Lösung war, eine UI zu haben, die ich per war file auf tomcat deploye und die "eigentliche" Funktionalität (Backend - REST Schnittstellen) als Standalone server laufen lasse.

Dort habe ich es so gemacht, dass die Plugins (jars) per ServiceLoader geladen werden und dann der Server damit gestartet wird

Java Code:
  1.  
  2. private void startServer() {
  3.     ResourceConfig resourceConfig = loadEndpoints();
  4.     resourceConfig.register(JacksonFeature.class);
  5.         // org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory.createHttpServer
  6.     httpServer = createHttpServer(URI.create(serverUrl), resourceConfig);
  7. }
  8.  
  9. // load all plugins
  10. private ResourceConfig loadEndpoints() {
  11.     ResourceConfig resourceConfig = new ResourceConfig();
  12.         // wrapper für einen simplen ServiceLoader. Alle REST Schnittstellen implementieren das Interface IntegrationEndpoint
  13.     serviceLoader.loadIntegrations(IntegrationEndpoint.class, resourceConfig::register);
  14.     return resourceConfig;
  15. }

Das laeuft alles auch so wie es soll, der Server wird gestartet mit allen plugins geladen, d.h. ich kann über die UI die dynamisch geladenen Schnittstellen erreichen.

Nun find ich es aber unhandlich einen eignen Server fürs Backend laufen zu lassen und die Idee ist nun, dass das Backend auch als war auf den selben Applicationserver deployed wird, wie die UI, also nur ein server, aber mit versch. Applications.

Und daran scheitere ich nun, das Backend so zu schreiben, dass mir die Ressourcen dynamisch geladen werden.

Ich habe zum Beispiel folgende Resource

Java Code:
  1. @Path("team")
  2. public class TeamEndpoint implements IntegrationEndpoint {
  3.   @GET
  4.   @Path("get")
  5.   @Produces(MediaType.TEXT_PLAIN)
  6.   public String getTeams() {
  7.      return "ALL TEAMS";
  8.   }
  9. }
die in ein jar gepackt wird und ins Filesystem abgelegt wird.

Meine backend application (wird als "backend" auf Tomcat deployed), nun soll diese beim Start laden und registrieren, mein bisheriger Versuch sieht so aus

Java Code:
  1.  
  2. @WebListener
  3. public class IntegrationServer extends ResourceConfig implements ServletContextListener {
  4.  
  5. public void contextInitialized(ServletContextEvent sce) {
  6.     LOGGER.info(() -> "CONTEXT INIT");
  7.     try {
  8.         register(JacksonFeature.class);
  9.         // wrapper for the ServiceLoader implementation
  10.         this.serviceLoader = new IntegrationServiceLoader();
  11.        this.serviceLoader.loadIntegrations(IntegrationEndpoint.class, gce -> {
  12.             LOGGER.info(() -> "Adding " + gce.getClass() + " to Server");
  13.             register(gce.getClass());
  14.         });
  15.     }
  16.     catch (IOException e) {
  17.         LOGGER.log(Level.SEVERE, e, () -> "Failed to init integration server");
  18.     }
  19. }
  20. }
Ich sehe ihm log, dass er registriert, aber der Aufruf http://localhost:8080/backend/team/get führt zu einem 404.

Meine web.xml ist recht simpel
Code:
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<servlet>
    <servlet-name>Jersey Web Application</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Jersey Web Application</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>
Wenn ich die Resource von oben direkt in dem Backend projekt habe und dann in der web.xml diese angebe, so wird sie korrekt geladen und registriert.

TL;DR: Wie kann ich in einer laufenden Web application Jersey rest service/resourcen dynamisch registrieren ?