首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在eclipse中的jetty中运行多个webapps

如何在eclipse中的jetty中运行多个webapps
EN

Stack Overflow用户
提问于 2019-06-13 16:19:42
回答 1查看 351关注 0票数 0

我正在尝试为eclipse中的gradle多web应用程序设置一个开发环境。这个应用程序部署在jetty的生产环境中,所以这就是我想在开发中使用的。我很难让eclipse运行所有的well应用程序,也不能进行调试。

我在网上找到的解决方案都使用插件,这些插件只能运行单个run应用程序。或者他们通过gradle (gretty)在服务器上运行webapps,这会导致调试问题。

我的源码是一个多项目的gradle应用。它编译正确,有docker脚本可以运行软件。在eclipse中,一切编译都没有错误,而且看起来运行得很好。然而,在eclipse中的jetty中,如何同时运行/调试所有的the应用程序,我感到无所适从。一些我可以用tomcat和websphere做的事情。

你们中有没有人能建议我一种方法,让我在eclipse中调试这个设置?理想情况下,我可以从gradle进行配置。我应该构建一个运行嵌入式服务器的项目吗?(这是否可以自动检测和使用我现有的web.xml文件?)或者我应该继续使用gretty (可以通过eclipse以一种直接的方式进行调试),或者是我缺少的其他工具?

我不可能是唯一一个有这种设置的人。解决此问题的通用解决方案是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-19 19:02:54

互联网上很少有专门涉及这个问题的信息。所以我会花时间来回答我自己的问题,希望它能对别人有所帮助。

Gretty无法处理这一点,gretty对你的应用程序做出了强有力的假设,如果你从一开始就建立了它,并坚持这些假设,那么你就很好,这可以是一个很大的帮助。但解决方案仍然缓慢且缺乏灵活性。

jetty没有eclipse插件,即使jetty是一个eclipse (基础)项目,wtp也帮不了你。

我最终选择了嵌入式jetty路线。这似乎比实际情况更难。但最终的结果就像是一种魔力。极快的启动时间(我们的12个webapp项目从30+秒变成了5秒)(格雷蒂花了几分钟)整个应用变得更加清晰。只有一个简单的java类来定义正在运行的内容。XML并不难读。

下面是基本结构

代码语言:javascript
复制
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);

带注释的扫描很好,我想要它。

代码语言:javascript
复制
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登录服务更难设置,它假定磁盘上有一个配置文件,而我没有该根目录,而且无论如何我都想从我自己的引导属性服务中获得它。

代码语言:javascript
复制
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。如果将上面的选项与文件进行比较,它们几乎是一对一的映射。

现在设置一个Now应用程序:

请注意,我是从我的多项目文件夹的根目录中启动这个类的,webapps位于该根目录下的子文件夹中。

另请注意,appname必须引用文件夹名称。它们所在的应用程序名称和文件夹名称在此设置中是相同的。

代码语言:javascript
复制
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);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56576260

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档