【问题标题】:How to run multiple webapps in jetty in eclipse如何在eclipse中的码头运行多个webapps
【发布时间】:2019-06-13 08:19:41
【问题描述】:

我正在尝试为 Eclipse 中的 gradle 多 Web 应用程序应用程序设置开发环境。该应用程序部署在码头上的生产中,所以这就是我想在开发中使用的。我无法让 eclipse 运行所有 webapps 并且也无法调试。

我已经能够找到只能运行单个 web 应用程序的在线使用插件的解决方案。或者他们通过 gradle (gretty) 在服务器中运行 webapps,然后导致调试问题。

我的来源是一个多项目 gradle 应用程序。它编译正确,有可以运行该软件的 docker 脚本。在 Eclipse 中,一切都编译没有错误,似乎工作正常。但是,我不知道如何在 Eclipse 中的码头同时实际运行/调试所有 webapps。我可以用 tomcat 和 websphere 做一些事情。

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

我不能是唯一使用此设置的人。常见的解决方案是什么?

【问题讨论】:

    标签: eclipse gradle web-applications jetty


    【解决方案1】:

    互联网上很少有专门针对此问题的信息。因此,我将花时间回答我自己的问题,希望对其他人有所帮助。

    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 登录服务更难设置,它假定磁盘上有一个配置文件,我没有那个 root,而且我还是想从我自己的引导属性服务中获得它。

    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。如果您将上述选项与文件进行比较,它们几乎是一对一的映射。

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

    请注意,我是从作为我的多项目文件夹根目录的文件夹开始的,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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-21
      • 2019-10-18
      • 1970-01-01
      • 1970-01-01
      • 2012-02-22
      • 1970-01-01
      • 2014-06-17
      • 1970-01-01
      相关资源
      最近更新 更多