簡體   English   中英

如何在eclipse中運行jetty中的多個webapps

[英]How to run multiple webapps in jetty in eclipse

我正在嘗試在eclipse中為gradle多Web應用程序應用程序設置開發環境。 該應用程序部署在碼頭上的生產中,這就是我想在開發中使用的內容。 我無法讓eclipse運行所有的webapps並且能夠進行調試。

我能夠在網上找到的解決方案使用的插件只能運行單個webapps。 或者他們通過服務器中的gradle(gretty)運行webapps,然后導致調試問題。

我的來源是一個多項目gradle應用程序。 它編譯得很好,有可以運行軟件的docker腳本。 在eclipse中,一切都編譯沒有錯誤,似乎工作正常。 我不知道如何在eclipse中同時在jetty中同時運行/調試所有的webapps。 我可以用tomcat和websphere做些什么。

你們中的任何一個人都可以告訴我一種讓我在eclipse中調試這個設置的方法嗎? 理想情況下,我可以從gradle配置。 我應該構建一個運行嵌入式服務器的項目嗎? (這可以自動檢測並使用我現有的web.xml文件嗎?)或者我應該繼續使用gretty(可以通過eclipse以簡單的方式進行調試)還是有其他工具我不知道?

我不能成為這個設置的唯一一個。 這個的常見解決方案是什么?

互聯網上的信息很少,專門解決這個問題。 所以我會花時間回答我自己的問題,希望能幫助別人。

Gretty無法處理這個問題,gretty對你的應用程序做出了強有力的假設,如果你從開始構建它來堅持那些假設你很好並且它可以是一個很好的幫助。 但解決方案仍然緩慢且不靈活。

jetty沒有eclipse插件,即使jetty是一個eclipse(基礎)項目,wtp也無法幫助你。

我最終采用了嵌入式碼頭路線。 這似乎比實際更難。 但最終的結果就像一個魅力。 非常快的啟動時間(我們的12個webapp項目從30秒到5秒)(Gretty需要幾分鍾)整個應用程序變得更加清晰。 有一個簡單的java類定義了正在運行的內容。 沒有難讀的XML。

這是基本結構

this.server = new Server(port);

setupAnnotationScanning(server);
setupJAASLoginService(server, config);

HandlerCollection hc = new HandlerCollection(true);
startWebApp(config, hc, "/app1", "app1");

// Root must be defined last or it will interfere with non root webapps
startWebApp(config, hc, "/", "rootapp");

server.setHandler(hc);

帶注釋的掃描很好,我想要它。

private static void setupAnnotationScanning(Server server) {
    Configuration.ClassList classlist = Configuration.ClassList.setServerDefault(server);
    classlist.addAfter("org.eclipse.jetty.webapp.FragmentConfiguration", "org.eclipse.jetty.plus.webapp.EnvConfiguration", "org.eclipse.jetty.plus.webapp.PlusConfiguration");
    classlist.addBefore("org.eclipse.jetty.webapp.JettyWebXmlConfiguration", "org.eclipse.jetty.annotations.AnnotationConfiguration");
}

JAAS登錄服務更難設置,它假設磁盤上的配置文件,我沒有那個根,我想從我自己的bootstrap屬性服務中得到它。

private static void setupJAASLoginService(Server server, BootstrapProperties config) throws Exception {
    JAASLoginService loginService = new JAASLoginService("ldaploginmodule");
    loginService.setName("WebRealm");
    loginService.setConfiguration(setupLDAPConfiguration(config));
    loginService.start();

    server.addBean(loginService);
}

private static javax.security.auth.login.Configuration setupLDAPConfiguration(BootstrapProperties config) {
  // Basically what I do here is make my own implementation of the Configuration and use it
  // The existing class assumes code to be in a very specific file location.
    return new javax.security.auth.login.Configuration() {
        @Override
        public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
            Map<String, Object> options = new HashMap<String, Object>();

            options.put("authenticationMethod", "simple");
            options.put("bindDn", config.get("ldap.bind.user"));
            options.put("bindPassword", config.get("ldap.bind.password"));
            options.put("contextFactory", "com.sun.jndi.ldap.LdapCtxFactory");
            options.put("debug", "true");
            options.put("forceBindingLogin", "true");
            options.put("hostname", config.get("ldap.host"));
            options.put("port", config.get("ldap.port"));
            options.put("roleBaseDn", config.get("ldap.groups.dn") + "," + config.get("ldap.root.dn"));/**/
            options.put("roleMemberAttribute", "uniqueMember");
            options.put("roleNameAttribute", "cn");
            options.put("roleObjectClass", "groupOfUniqueNames");
            options.put("userBaseDn", config.get("ldap.people.dn") + "," + config.get("ldap.root.dn"));/**/
            options.put("userIdAttribute", "uid");
            options.put("userObjectClass", "caUser");
            options.put("userPasswordAttribute", "userPassword");
            options.put("userRdnAttribute", "cn");

            AppConfigurationEntry cfg = new AppConfigurationEntry("org.eclipse.jetty.jaas.spi.LdapLoginModule", LoginModuleControlFlag.REQUIRED, options);
            return new AppConfigurationEntry[] { cfg };
        }
    };
}

您可能必須更改選項以匹配您自己的ldap。 如果將上述選項與文件進行比較,則它們幾乎是一對一的映射。

現在設置一個webapp:

請注意,我從一個文件夾啟動此類,該文件夾是我的多項目文件夾的根目錄,webapps位於該根目錄下的子文件夾中。

另請注意,appname必須引用文件夾名稱。 它們所在的應用程序名稱和文件夾名稱在此設置中是相同的。

private static void startWebApp(BootstrapProperties config, HandlerCollection hc, String contextRoot, String appName) throws Exception {
    boolean isProd = config.getBoolean("isProduction", false);

  // When running a production server you're probably working from warfiles.
  // In dev you're working from eclipse webapp folders (WebContent/webapp/the place where your index.html resides)
    String pathStr = isProd
            ? "dist/webapps/" + appName + ".war"
            : "webapps/" + appName;

    WebAppContext context = new WebAppContext();
    // This is where you can find the webapp on your server http://example.com{/contextRoot}
    context.setContextPath(contextRoot);
    // Optional, but I found it very useful for debugging
    context.addLifeCycleListener(LIFE_CYCLE_LISTENER);

    // Very important if you want JSTL to work, otherwise you get the error:
    // The absolute uri: [http://java.sun.com/jsp/jstl/core] cannot be resolved in
    // either web.xml or the jar files deployed with this application
    // This was very hard to figure out!
    context.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", ".*/[^/]*jstl.*\\.jar$");

    if (isProd) {
        // Again production server refers to warfile, simple basic function for jetty.
        context.setWar(pathStr);

    } else {
        // Otherwise things get a little more complicated
        // For me the app and classes folders are in two separate places.
        // But fortunately Jetty still supports that.
        Path path = Paths.get(pathStr);
        Path basePath = path.toRealPath();

        // These are folders in your eclipse projects 
        Path appFolder = basePath.resolve("webapp"); // WebContent also often used
        Path classesPath = basePath.resolve("bin/main"); 

        if (Files.exists(appFolder)) {
            context.setBaseResource(new PathResource(appFolder));
            LOGGER.log(Level.FINE, " webapp " + appFolder);
        }
        if (Files.exists(classesPath)) {
            context.setExtraClasspath(classesPath.toString());
            LOGGER.log(Level.FINE, " classes " + classesPath);
        }

        // A pure webapp project without classes works fine classesPath wont exist and is thus not added.
    }

    // Add to the handler context.
    hc.addHandler(context);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM