2013-06-17 27 views
5

Próbuję wykryć, czy aplikacja działa na środowisku Eclipse Jetty jako kontener serwletu. Znalazłem solution for Mortbay Jetty, ale nie dla rzeczywistej wersji z Eclipse. Zmodyfikowałem istniejący czek i zastąpiłem ścieżkę Classpath z "/org/mortbay/jetty/Server.class" do "/org/eclipse/jetty/server/Server.class", ale sprawdzanie zakończyło się niepowodzeniem na Jetty 9. Uruchomienie tej samej aplikacji tomcat się powiódł. Co ja źle zrobiłem?Wykryj, czy działający kontener serwletu to Eclipse Jetty

Kod wygląda następująco:

private boolean detect(final String clazz) { 
    try { 
    final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 
    systemClassLoader.loadClass(clazz); 
    return true; 
    } catch (final ClassNotFoundException cnfe) { 
    final Class<?> classObj = getClass(); 
     if (classObj.getResource(clazz) != null) { 
     return true; 
    } else { 
     return false; 
     } 
    } 
} 

funkcji o nazwie z:

detect("/org/eclipse/jetty/server/Server.class"); 

Odpowiedz

3

Wejście do klasy serwera można zrobić z trybu osadzonego, ale nie samodzielnym Jetty. Dzieje się tak, ponieważ WebAppClassloader izoluje dostęp do klasy org.eclipse.jetty.server.Server na aplikacje internetowe.

Można jednak użyć faktu, że cały kontener serwletu musi mieć implementację serwletu default, wystarczy użyć ServletContext, aby uzyskać dostęp do RequestDispatcher dla domyślnego serwletu i zwrócić uwagę na nazwę klasy implementacji. Wygląda na to, że działa dobrze zarówno na Jetty 8.1.10, jak i 9.0.3 podczas używania wbudowanego. (Spróbuje ponownie na samodzielny molo wkrótce)

Pełna klasy jako przykład:

package com.company.foo; 

import java.io.IOException; 
import java.io.PrintWriter; 
import java.lang.reflect.Method; 

import javax.servlet.RequestDispatcher; 
import javax.servlet.ServletException; 
import javax.servlet.annotation.WebServlet; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

@WebServlet(urlPatterns = { "/detect" }) 
@SuppressWarnings("serial") 
public class DetectServlet extends HttpServlet 
{ 
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
    { 
     resp.setContentType("text/plain"); 
     PrintWriter out = resp.getWriter(); 
     detect(out,"org.eclipse.jetty.server.Server"); 
     detect(out,"/org/eclipse/jetty/server/Server.class"); 
     detect(out,"org.eclipse.jetty.server.Request"); 
     detect(out,"/org/eclipse/jetty/server/Request.class"); 
     detect(out,"org.mortbay.jetty.Server"); 
     detect(out,"/org/mortbay/jetty/Server.class"); 

     detectDefaultServlet(out, req, "org.eclipse.jetty"); 
     detectDefaultServlet(out, req, "org.apache.catalina"); 

     String version = getReflectedMethodValue("org.eclipse.jetty.server.Server", "getVersion"); 
     out.printf("Server.getVersion() = %s%n", version); 
    } 

    private void detectDefaultServlet(PrintWriter out, HttpServletRequest req, String keyword) 
    { 
     // Request the default servlet (its pretty safe to say it will always be there) 
     RequestDispatcher dispatcher = req.getServletContext().getNamedDispatcher("default"); 
     if(dispatcher == null) { 
      out.printf("detectDefaultServlet(out, req, \"%s\") = <no default servlet>%n", keyword); 
      return; 
     } 

     // If the request dispatcher implementation contains the keyword, we can claim a match 
     boolean detected = dispatcher.getClass().getName().contains(keyword); 
     out.printf("detectDefaultServlet(out, req, \"%s\") = %b (%s)%n", keyword, detected, dispatcher.getClass().getName()); 
    } 

    private String getReflectedMethodValue(String clazzName, String methodName) 
    { 
     ClassLoader loader = ClassLoader.getSystemClassLoader(); 
     try 
     { 
      Class<?> clazz = Class.forName(clazzName,false,loader); 
      Class<?> parameterTypes[] = new Class<?>[0]; 
      Method method = clazz.getDeclaredMethod(methodName,parameterTypes); 
      Object args[] = new Object[0]; 
      return (String)method.invoke(clazz,args); 
     } 
     catch (ClassNotFoundException e) 
     { 
      return "<class-not-found>"; 
     } 
     catch (Throwable t) 
     { 
      return "<" + t.getClass().getName() + ": " + t.getMessage() + ">"; 
     } 
    } 

    private void detect(PrintWriter out, String resource) 
    { 
     out.printf("detect(\"%s\") = %b%n",resource,detected(resource)); 
    } 

    private boolean detected(String clazz) 
    { 
     try 
     { 
      ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 

      systemClassLoader.loadClass(clazz); 

      return true; 
     } 
     catch (ClassNotFoundException cnfe) 
     { 
      Class<?> classObj = getClass(); 

      if (classObj.getResource(clazz) != null) 
      { 
       return true; 
      } 
      else 
      { 
       return false; 
      } 
     } 
    } 
} 

Który będzie następujący wynik na Jetty 8.1.10 wbudowanego

detect("org.eclipse.jetty.server.Server") = true 
detect("/org/eclipse/jetty/server/Server.class") = true 
detect("org.eclipse.jetty.server.Request") = true 
detect("/org/eclipse/jetty/server/Request.class") = true 
detect("org.mortbay.jetty.Server") = false 
detect("/org/mortbay/jetty/Server.class") = false 
detectDefaultServlet(out, req, "org.eclipse.jetty") = true (org.eclipse.jetty.server.Dispatcher) 
detectDefaultServlet(out, req, "org.apache.catalina") = false (org.eclipse.jetty.server.Dispatcher) 
Server.getVersion() = 8.1.10.v20130312 

i podobne wyjście na Jetty 9.0.3 Wbudowany

detect("org.eclipse.jetty.server.Server") = true 
detect("/org/eclipse/jetty/server/Server.class") = true 
detect("org.eclipse.jetty.server.Request") = true 
detect("/org/eclipse/jetty/server/Request.class") = true 
detect("org.mortbay.jetty.Server") = false 
detect("/org/mortbay/jetty/Server.class") = false 
detectDefaultServlet(out, req, "org.eclipse.jetty") = true (org.eclipse.jetty.server.Dispatcher) 
detectDefaultServlet(out, req, "org.apache.catalina") = false (org.eclipse.jetty.server.Dispatcher) 
Server.getVersion() = 9.0.3.v20130506 

Ale inna dla Jetty 9.0.3 Samodzielny

detect("org.eclipse.jetty.server.Server") = false 
detect("/org/eclipse/jetty/server/Server.class") = false 
detect("org.eclipse.jetty.server.Request") = false 
detect("/org/eclipse/jetty/server/Request.class") = false 
detect("org.mortbay.jetty.Server") = false 
detect("/org/mortbay/jetty/Server.class") = false 
detectDefaultServlet(out, req, "org.eclipse.jetty") = true (org.eclipse.jetty.server.Dispatcher) 
detectDefaultServlet(out, req, "org.apache.catalina") = false (org.eclipse.jetty.server.Dispatcher) 
Server.getVersion() = <class-not-found> 
+0

Przyjdź, aby myśleć o tym, można użyć dowolnego interfejsu Servlet i sprawdzić, czy nazwa klasy realizacja rozpoczyna się od '„org.eclipse.jetty.”' –

+0

To działa. Dziękuję Ci bardzo! – DaSilva2010