当前位置: 首页 > 知识库问答 >
问题:

如何在日食中的码头运行多个Web应用程序

蒋正平
2023-03-14

我正在尝试为 eclipse 中的 gradle 多 Web 应用程序应用程序设置一个开发环境。该应用程序部署在码头上的生产环境中,因此这就是我想要在开发中使用的应用程序。我在让eclipse运行所有Web应用程序并能够调试时遇到问题。

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

我的来源是一个多项目级应用程序。它可以正确编译,有可以运行软件的docker脚本。在 eclipse 中,一切都可以编译而不会出错,并且似乎工作正常。然而,我不知所措,如何在eclipse的码头同时实际运行/调试所有Web应用程序。我可以用tomcat和websphere做一些事情。

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

我不能是唯一一个拥有此设置的人。对此的常见解决方案是什么?

共有1个答案

昌和悦
2023-03-14

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

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登录服务更难设置,它假定磁盘上有一个配置文件,我没有那个根目录,我希望它来自我自己的引导属性服务。

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);
}
 类似资料:
  • 我正在尝试在Tomcat上部署多个spring boot web应用程序。所有应用程序都有相同的application.properties。如何拆分在Tomcat上运行的不同应用程序的配置文件。

  • 如何在同一台服务器上独立运行多个web应用程序? docker是正确的方法(请举例说明)还是矫枉过正? 有没有其他选择我应该考虑? 我还需要考虑其他问题(潜在问题、解决方案)吗?

  • 问题内容: 我想使用html applet标记在我的Web应用程序中运行简单applet,但是它给出了类似的错误 java.lang.ClassNotFoundException:MyApplet 请给我示例应用程序,如果可能的话..... 问题答案: 问题是applet引擎在您定义的代码库中找不到MyApplet类。 这是因为您在/ WEB-INF / classes目录中进行了分类。该目录受s

  • 问题内容: 我想知道如何在Java中运行PHP代码。使用ScriptEngine,我可以运行JavaScript: 为此,我导入了库。我相信要运行PHP,我必须导入一个类似的库,并将上面代码的第三行更改为extension 。不幸的是,我不知道这是哪个库。我已经用Google搜索并找到了答案,并遇到了PHP / Java Bridge库,但是我认为这并不是我要找的,因为它专注于通过PHP运行Jav

  • 问题内容: 有没有人找到一种在IIS中运行Java Web应用程序的方法?在我看来,完全有可能编写一个ISAPI插件(对吗?),该插件将Jetty或自定义servlet容器与IIS集成在一起。这样做的好处是,许多出色的高端Java应用程序(如Jira)需要用于其他所有Microsoft商店的单独基础结构。 问题答案: 我认为您会发现使用以下两篇文章 使用Microsoft的Internet Inf

  • 问题内容: 这个问题是我继续研究Docker的一部分,并且在某些方面跟进了我先前的问题之一。我现在已经了解了如何通过将一堆Docker容器链接在一起来获得完整的应用程序堆栈(实际上是微型VPS)。例如,可以创建一个堆栈,为Apache+ PHP5提供一堆扩展名+ Redis + MemCached+MySQL,它们都在Ubuntu上运行,无论是否带有附加数据容器,都可以轻松地序列化用户数据。 一切