将 Jetty 6.1 迁移到 9.3 有多个问题

Migrating Jetty 6.1 to 9.3 has multiple issue

Hi All need few suggestion while migrating our legacy application which has in-built jetty server 6.1.

I am trying to migrate to Jetty 9.3, yes after long gap and after decided to move to JAVA 8. While changing few of the files I encounter piece of code written in jetty 6.1.

Code:

@Override
    public void initialize(final ServiceConfiguration genericConfig, final Controller controller, final int serviceId,
        final ServiceLock lock) throws Exception {
        if (genericConfig instanceof JettyServerConfiguration) {
            configuration = (JettyServerConfiguration) genericConfig;
        } else {
            configuration = XmlConfigurable.createInstance(JettyServerConfiguration.class,
                    genericConfig.getXmlConfigElement());
        }

        server = new Server();
        log.info("jetty version = " + Server.getVersion()); //frozen

        maxWaitForSlave = getConfiguration().getMaxWaitForSlave();

        final boolean debug = getConfiguration().getMortBayDebug();
        log.info("mortbay debug = '" + debug + "'"); //frozen
        org.mortbay.log.Log.getLog().setDebugEnabled(debug);

        // Configure http
        final boolean httpEnabled = getConfiguration().getHttpEnabled();

        if (httpEnabled) {
            // Setup http connector as nio or socket.
            final boolean nio = getConfiguration().getNioEnabled();
            Connector connector;

            if (nio) {
                connector = new SelectChannelConnector();
            } else {
                connector = new SocketConnector();
            }

            final int mainPort = getConfiguration().getHttpPort();

            log.info("adding default connector on port '" + mainPort + "'"); //frozen
            connector.setPort(mainPort);

            server.addConnector(connector);
        }

        // Configure SSL
        final boolean sslEnabled = getConfiguration().getSslEnabled();

        if (sslEnabled) {
            final int sslPort = getConfiguration().getSslPort();
            final String sslKeyStore = getConfiguration().getSslKeyStore();
            final String sslPassword = getConfiguration().getSslPassword();
            final String sslKeyPassword = getConfiguration().getSslKeyPassword();
            final String sslTrustPassword = getConfiguration().getSslTrustPassword();

            //final boolean nio = configuration.getBooleanValue("NioEnabled", false); //frozen
            //if(nio) {
            //sslConnector = new SslSelectChannelConnector();  available in jetty 7
            //} else {
            final SslSocketConnector sslConnector = new SslSocketConnector();
            sslConnector.setKeystore(sslKeyStore);
            sslConnector.setTruststore(sslKeyStore);
            sslConnector.setPassword(sslPassword);
            sslConnector.setKeyPassword(sslKeyPassword);
            sslConnector.setTrustPassword(sslTrustPassword);
            sslConnector.setPort(sslPort);
            log.info("adding ssl connector on port '" + sslPort + "'"); //frozen
            server.addConnector(sslConnector);

            //}
        }

        // Check we had 1 connector else the server is useless
        if (server.getConnectors().length == 0) {
            throw new FileNotFoundException("No connectors registered.  Please see HttpEnable or SslEnable XML tags."); //frozen
        }

        // Configure the handlers
        final HandlerCollection handlers = new HandlerCollection();

        for (final WebAppContext webAppContext : getConfiguration().getWebAppContexts()) {
            log.info("Adding WebAppContext " + webAppContext.getWar() + " at " + webAppContext.getContextPath()); //frozen
            handlers.addHandler(webAppContext);
        }

        // See http://docs.codehaus.org/display/JETTY/Logging+Requests
        final boolean accessLogEnabled = getConfiguration().getLogEnabled();

        if (accessLogEnabled) {
            final RequestLogHandler requestLogHandler = new RequestLogHandler();
            final File logDir = ServiceUtilities.getLogDirectory();

            if (!logDir.exists()) {
                logDir.mkdirs();
            }

            final File logFile = new File(getConfiguration().getLogFormat());

            if (!logFile.getParentFile().exists()) {
                logFile.getParentFile().mkdirs();
            }

            final NCSARequestLog requestLog = new NCSARequestLog(getConfiguration().getLogFormat());
            requestLog.setRetainDays(getConfiguration().getLogRetain());
            requestLog.setAppend(getConfiguration().getLogAppend());
            requestLog.setExtended(getConfiguration().getLogExtended());
            requestLog.setLogTimeZone(getConfiguration().getLogTz());
            requestLog.setLogLatency(getConfiguration().getLogLatency());
            requestLogHandler.setRequestLog(requestLog);
            handlers.addHandler(requestLogHandler);
        }

        handlers.addHandler(new DefaultHandler());

        server.setHandler(handlers);

        server.setUserRealms(new UserRealm[] { new OSMUserRealm() });

        JettyServerInfo.install(server);

        super.initialize(configuration, controller, serviceId, lock);
    }

After the suggestion given below , I have re-written it like:

@Override
public void initialize(final ServiceConfiguration genericConfig, final Controller controller, final int serviceId,
    final ServiceLock lock) throws Exception {
    if (genericConfig instanceof JettyServerConfiguration) {
        configuration = (JettyServerConfiguration) genericConfig;
    } else {
        configuration = XmlConfigurable.createInstance(JettyServerConfiguration.class,
                genericConfig.getXmlConfigElement());
    }

    server = new Server();
    log.info("jetty version = " + Server.getVersion()); //frozen

    maxWaitForSlave = getConfiguration().getMaxWaitForSlave();

    final boolean debug = getConfiguration().getMortBayDebug();
    log.info("mortbay debug = '" + debug + "'"); //frozen
    //org.eclipse.jetty.util.log.Log.getLog().setDebugEnabled(debug);


        //Re-writing code for Jetty 9.3
        final int mainPort = getConfiguration().getHttpPort();//8580
        final int sslPort = getConfiguration().getSslPort(); //8581
        final String sslKeyStore = getConfiguration().getSslKeyStore();
        final String sslPassword = getConfiguration().getSslPassword();
        final String sslKeyPassword = getConfiguration().getSslKeyPassword();
        final String sslTrustPassword = getConfiguration().getSslTrustPassword();
        //Added for  Jetty 9.3
        final KeyStore trustKeyStore=KeyStore.getInstance(getConfiguration().getSslKeyStore());

        ClassLoader cl = JettyServer.class.getClassLoader();// Get the class loader for my current class which is JettyServer
        String keystoreResource = "ssl/keystore";
         URL f = cl.getResource(keystoreResource);

         if (f == null)
         {
             throw new RuntimeException("Unable to find " + keystoreResource);
         }

         // Setup HTTP Connector
         HttpConfiguration httpConf = new HttpConfiguration();
         httpConf.setSecurePort(mainPort);
         httpConf.setSecureScheme("https");

         // Establish the HTTP ServerConnector
         ServerConnector httpConnector = new ServerConnector(server,
                 new HttpConnectionFactory(httpConf));
         httpConnector.setPort(mainPort);
         server.addConnector(httpConnector);

         // Setup SSL
        SslContextFactory theSSLFactory = new SslContextFactory();

        theSSLFactory.setKeyStorePath(f.toExternalForm());  //replaced for--> theSSLFactory.setKeyStorePath(sslKeyStore);
        theSSLFactory.setKeyManagerPassword(sslPassword);  // or this one ? seems hardcoded --> sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
        theSSLFactory.setKeyStorePassword(sslKeyPassword); // or this one ? seems hardcoded --> sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
        theSSLFactory.setTrustStore(trustKeyStore);
        theSSLFactory.setTrustStorePassword(sslTrustPassword);

        // Setup HTTPS Configuration
        HttpConfiguration httpsConf = new HttpConfiguration(httpConf);
        httpsConf.addCustomizer(new SecureRequestCustomizer()); // adds ssl info to request object

     // Establish the HTTPS ServerConnector
        ServerConnector httpsConnector = new ServerConnector(server,
                new SslConnectionFactory(theSSLFactory,"http/1.1"),
                new HttpConnectionFactory(httpsConf));
        httpsConnector.setPort(sslPort);

        log.info("adding ssl connector on port '" + sslPort + "'"); //frozen
        server.addConnector(httpsConnector);



    // Check we had 1 connector else the server is useless
    if (server.getConnectors().length == 0) {
        throw new FileNotFoundException("No connectors registered.  Please see HttpEnable or SslEnable XML tags."); //frozen
    }

    // Configure the handlers
    final HandlerCollection handlers = new HandlerCollection();

    for (final WebAppContext webAppContext : getConfiguration().getWebAppContexts()) {
        log.info("Adding WebAppContext " + webAppContext.getWar() + " at " + webAppContext.getContextPath()); //frozen
        handlers.addHandler(webAppContext);
    }

    // See http://docs.codehaus.org/display/JETTY/Logging+Requests
    final boolean accessLogEnabled = getConfiguration().getLogEnabled();

    if (accessLogEnabled) {
        final RequestLogHandler requestLogHandler = new RequestLogHandler();
        final File logDir = ServiceUtilities.getLogDirectory();

        if (!logDir.exists()) {
            logDir.mkdirs();
        }

        final File logFile = new File(getConfiguration().getLogFormat());

        if (!logFile.getParentFile().exists()) {
            logFile.getParentFile().mkdirs();
        }

        final NCSARequestLog requestLog = new NCSARequestLog(getConfiguration().getLogFormat());
        requestLog.setRetainDays(getConfiguration().getLogRetain());
        requestLog.setAppend(getConfiguration().getLogAppend());
        requestLog.setExtended(getConfiguration().getLogExtended());
        requestLog.setLogTimeZone(getConfiguration().getLogTz());
        requestLog.setLogLatency(getConfiguration().getLogLatency());
        requestLogHandler.setRequestLog(requestLog);
        handlers.addHandler(requestLogHandler);
    }

    handlers.addHandler(new DefaultHandler());

    server.setHandler(handlers);

    server.setUserRealms(new UserRealm[] { new OSMUserRealm() });

    JettyServerInfo.install(server);

    super.initialize(configuration, controller, serviceId, lock);
}

Still I am not sure what to do with this line.

server.setUserRealms(new UserRealm[] { new OSMUserRealm() });

I didn't find any alternative method in jetty 9.3 for UserRealm, any suggestion how can I re-write this line of code?

Reminder: Jetty versioning (since 1995) is <servlet_support>.<major_version>.<minor_version>

恭喜,您实际上已经跳过了 Jetty 中的 14 个主要版本。 :-)

难怪看起来这么吓人。

decided to move to JAVA 8

知道January 2019 is the last day of Java 8 public updates。 对于非付费的 Oracle 客户来说,这实际上是生命的终结。

注意:Java9 已被弃用/不受支持。

由于您提到使用 SSL/TLS,因此 必须使您的 JVM 保持最新并且 not use an expired JVM(浏览器要求和 TLS 要求)。

考虑在今年 (2018) 结束之前(再次)升级到 Java 11。

java 的更新周期正在加快,不要指望 Java 版本会持续多年。预计主要版本不会持续超过 6 个月(目前)。

log.info("mortbay debug = '" + debug + "'"); //frozen org.eclipse.jetty.util.log.Log.getLog().setDebugEnabled(debug);

日志记录不是这样工作的。

这取决于选择的实现(现在有 SLf4j、java.util.logging 和 System.err)。使用 Log.getLog() 可以获得根日志外观,而在外观上使用 setDebugEnabled() 只是在外观上设置调试,而不是实际的记录器。

使用正确的日志记录实现和命名记录器。

if (nio) { connector = new SelectChannelConnector(server); } else {
connector = new SocketConnector(server); }

不再有阻塞连接器,它 100% 基于 NIO(对于过去的 5 个主要版本)

欢迎来到现代网络协议的世界。

连接器仅服务于 1 种协议的日子已经一去不复返了,现在所有协议都在实际连接期间协商。

例如:Connect, TLS, ALPN, HTTP/2, HTTP/1.1 with TLS, HTTP/1.1 without TLS, etc.单个连接的 TLS 协商也用于确定您与哪个 webapp 交谈,使用什么主机,以及什么证书等)

ServerConnector 的作用是只监听一个端口,您分配给 ServerConnector 的 ConnectionFactories 决定如何处理该连接。

为此阅读各种示例代码。

参见:

一个简化的例子:

    Server server = new Server();
    int httpsPort = 8443;

    // Find Keystore
    ClassLoader cl = ServerConnectorHttps.class.getClassLoader();
    String keystoreResource = "ssl/keystore";
    URL f = cl.getResource(keystoreResource);
    if (f == null)
    {
        throw new RuntimeException("Unable to find " + keystoreResource);
    }

    // Setup SSL
    SslContextFactory sslContextFactory = new SslContextFactory();
    sslContextFactory.setKeyStorePath(f.toExternalForm());
    sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
    sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");

    // Setup HTTPS Configuration
    HttpConfiguration httpsConf = new HttpConfiguration();
    httpsConf.setSecurePort(httpsPort);
    httpsConf.setSecureScheme("https");
    httpsConf.addCustomizer(new SecureRequestCustomizer()); // adds ssl info to request object

    // Establish the ServerConnector
    ServerConnector httpsConnector = new ServerConnector(server,
            new SslConnectionFactory(sslContextFactory,"http/1.1"),
            new HttpConnectionFactory(httpsConf));
    httpsConnector.setPort(httpsPort);

    server.addConnector(httpsConnector);

    // Add a Handler for requests
    server.setHandler(new HelloHandler("Hello Secure World"));

    server.start();
    server.join();
}

server.setUserRealms(new UserRealm[] { new OSMUserRealm() }); I didn't find any alternative method in jetty 9.3 for UserRealm, any suggestion how can I re-write this line of code?

安全由 LoginService 处理,一个 LoginService 可以拥有一个领域(如果该 LoginService 支持这样的概念)。

LoginService 可以作为服务器上的 Bean,但这只是为了控制 LoginService 的生命周期。

具有安全上下文设置以使用特定领域的 WebAppContext 将查找服务器上的所有 LoginService bean 并使用与指定领域匹配的那个。