我对 Virgo 和 Eclipse RAP 的初体验

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

几个月前,我还没有意识到 RAP 应用程序,实际上 是任何 Eclipse 应用程序,在本地 Jetty 服务器上运行不会自动在服务器上运行。我仍然不确定为什么会这样,但是当在重要演示的前一天意识到这一点时,我想原因并没有那么重要。

无论如何,吸取的教训是,当一个人想在服务器上运行 Eclipse 应用程序时,您将需要一个基于 JAVA 的应用程序服务器,而我的选择落在了 Virgo 上,因为它似乎是最符合 OSGI 的应用程序服务器。由于我花了大约四个星期的时间才按照我想要的方式启动和运行所有内容,我觉得在线教程可能需要更新一些,所以我希望我的经验可能对其他开发人员有所帮助,因为 Virgo 确实如此提升您的 OSGI 应用程序的可能性……一旦您度过难关!

服务器端

让 Virgo 在服务器上运行真的是一个非常简单的任务!就我而言,我们有一个在云中运行的 Debian Linux 发行版。处女座在三个操作后启动并运行:

  1. 设置 JAVA
  2. 将 Virgo 发行版复制到发行版
  3. 创建启动脚本。

在我们的例子中,我们需要一个 来自 Oracle 的 JAVA 7 JDK ,因为我们想要运行一个 Cassandra 客户端,而该客户端当时不适用于 JAVA 6,即 OpenJDK。当时的版本。让 JAVA7 在 Debian 上运行只是一个简单的问题:

  • JDK 解压缩到 Debian 上的一个文件夹中(我们使用 /opt)
  • 将 JAVA_HOME 设置为 /etc/profile 文件中文件夹的根目录
  • 使用 sources /etc/profile 命令更新系统

获取服务器上的Virgo distribution与上述步骤基本相同,唯一不同的是需要在 profile 文件中添加环境变量 SERVER_HOME 。然而,选择正确的处女座分布需要更多的思考!

选择正确的处女座分布

处女座有多种口味:

  • Nano 是一个最小的应用程序服务器,适用于单个应用程序
  • Kernel 提供了一个功能齐全但很简单的应用程序服务器,它可以通过以下方式进行扩展
  • Jetty-Server tomcat-server 以提供 Web 内容。

在 Eclipse RAP 负责人 Ralf Steinberg 的这篇 文章 之后,我们最初选择了为 RAP 扩展的 nano 发行版,在撰写本文时, Virgo 构建服务器上提供了 3.7.0 版本的 Virgo。 其中包括 纳米说唱 分布。我们在服务器上安装了这个版本,并设法让我们的 RAP 应用程序正常工作,但很快就发现这种方法只适用于非常小的 RAP 应用程序。

由于 Virgo Nano 不包括内核的 用户区域 功能,您只能通过将必要的 OSGI 包一个一个地拖放到 pickup 目录中来构建您的应用程序。这些 bundle 需要以尊重依赖关系的方式放入目录中,因此如果 bundle A bundle B 有依赖关系,则必须首先将 bundle B 放入目录中。这种方法非常适合测试,但即使是中等规模的应用程序也会出现问题,更不用说必须为多个应用程序提供服务了。我们打算部署四个应用程序,其中一些共享功能,例如数据库连接,因此这种方法很快变得很麻烦。它经常被提及,但 Virgo 通过其 管理控制台 提供的支持确实很棒。 可维护性 文件夹中的日志也很有帮助!

对我们来说,合乎逻辑的选择是选择 码头服务器 分布。这个发行版有更好的方法来管理多个应用程序,并且默认提供码头服务器。 Florian Waibel 的这些帖子很好地介绍了在此发行版上设置 RAP 应用程序:

据我所知(据我测试),这些信息在很大程度上仍然有效,唯一的评论是 Virgo 工具 目前没有积极开发,并且落后于 Eclipse Luna 和 Mars 版本。该工具允许您将 Virgo 集成到您的 Eclipse IDE 中,但这在当时并不是主要问题。我对码头服务器不是很满意,因为分发看起来非常像“正​​在进行的工作”。 ext 用户区域中的许多捆绑包都是双重的,这使得使用管理控制台进行调试非常复杂。

然而,最让我感到困惑的是,在 Florian 的两篇文章中,RAP 应用程序不能在没有任何额外编码的情况下放入应用程序服务器!您必须在您的包中包含一个 SpringDM bean,或者您必须通过在您的 MANIFEST.MF 文件中包含一个 Web-Context 指令以及包根目录下的一个 WEB-INF 文件夹来使您的包成为一个 Web 包。在 nano-rap 发行版中,这是不需要的,所以我决定看看我是否可以自己创建一个“两全其美”的 Virgo 版本。这花了我几天的时间,我还没有达到我的目标,但它帮助我更好地了解了处女座服务器!

自定义 Virgo 应用服务器

因此,我制作了一个自定义 Virgo 应用程序服务器,方法是:

  • 内核 分发开始
  • nano-rap 发行版中的 Jetty 文件和 RAP 文件添加到 ext 文件夹

  • 添加 jetty-8.1.3 计划和 rap-1.5 计划(我升级到 RAP 2.3.0 没有问题),如 Florian 的 帖子 中所述。
  • 据我所知,此设置创建了最精简的发行版,它支持内核的所有功能,并且“RAP 就绪”。因此,我将 Virgo 内核 分发版添加到我的 Linux 服务器,将其解压缩到 /opt 文件夹,如上所述在配置文件中设置 SERVER_HOME 变量,然后启动它。通过在浏览器中检查 <my.server.ip.address>:8080/admin/console 地址,我可以看到一切正常。现在我需要配置这个设置。

    配置 Virgo 内核

    当 Virgo Kernel 发行版启动并运行时,管理控制台由位于 plugins 文件夹中的 org.eclipse.equinox.http 包提供服务。这个包需要用 Jetty 替换——否则你会遇到网络问题,因为它们都使用 config.ini 来选择它们运行的​​端口。大多数教程会邀请您将 jetty 包放在 ext 文件夹中,但我们选择添加一个名为 rap 的新 user region ,我们想在其中放置 jetty 和 rap 包。一旦您知道该怎么做,这是一项非常简单的任务。我们选择了这个,因为 ext 已经用于添加 gemini blueprint 功能,并且出于维护的原因,我们不想在一个文件夹中混合功能。

    首先,我们需要从配置文件夹中选择 org.eclipse.virgo.repository 属性文件,并添加以下行(粗体):

    ext.type=external
    ext.searchPattern=repository/ext/{artifact}

    usr.type=watched
    usr.watchDirectory=repository/usr

    #RAP extension
    rap.type=external
    rap.searchPattern=repository/rap/{artifact}

    chain=ext,usr, rap

    这些行告诉 Virgo 应用程序服务器,一个名为 rap 的新存储库将添加到用户区域,它实际上位于 repository 文件夹中。

    接下来,我们需要创建文件夹并用所需的包填充它:


    如您所见,捆绑包扩展了两个 Virgo 计划, 其中包括:

    • 文件夹中包的启动顺序
    • 哪些捆绑包可用于用户区域的其他文件夹中的捆绑包。

    添加到 org.eclipse.virgo.repository 属性文件的每个文件夹基本上都是一个独立的模块,其范围由它所在的文件夹决定。该计划使这些包可用于更广泛的用途。

    这两个计划都是从 Florian 的 帖子中 逐字复制(和修改)的,为了完整起见,将其包含在此处。 Jetty计划如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <plan name="org.eclipse.jetty" version="8.1.3" scoped="false" atomic="true"
    xmlns="http://www.eclipse.org/virgo/schema/plan"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
    http://www.eclipse.org/virgo/schema/plan
    http://www.eclipse.org/virgo/schema/plan/eclipse-virgo-plan.xsd">

    <artifact type="bundle" name="javax.servlet" version="[3, 4)" />
    <artifact type="bundle" name="org.eclipse.jetty.util" version="[8.1.3, 9)" />
    <artifact type="bundle" name="org.eclipse.jetty.io" version="[8.1.3, 9)" />
    <artifact type="bundle" name="org.eclipse.jetty.http" version="[8.1.3, 9)" />
    <artifact type="bundle" name="org.eclipse.jetty.servlet" version="[8.1.3, 9)" />

    <artifact type="bundle" name="org.eclipse.equinox.http.servlet" version="[1.1.300, 2)" />
    <artifact type="bundle" name="org.eclipse.equinox.http.jetty" version="[3.0.0, 4)" />
    </plan>

    RAP-2.3.0 计划如下所示:

    <?xml version="1.0" encoding="UTF-8"?>
    <plan name="org.eclipse.rap" version="2.3.0" scoped="false" atomic="true"
    xmlns="http://www.eclipse.org/virgo/schema/plan"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
    http://www.eclipse.org/virgo/schema/plan
    http://www.eclipse.org/virgo/schema/plan/eclipse-virgo-plan.xsd">

    <artifact type="bundle" name="org.eclipse.rap.rwt" version="[2.3.0, 4.0.0)" />
    <artifact type="bundle" name="org.eclipse.rap.rwt.osgi" version="[2.3.0, 4.0.0)" />
    <artifact type="bundle" name="org.eclipse.rap.jface" version="[2.3.0, 4.0.0)" />
    <artifact type="bundle" name="org.eclipse.rap.jface.databinding" version="[2.3.0, 4.0.0)" />
    </plan>

    有关 Virgo 计划的详细信息,请参阅 相关文档 。对于这里的讨论,有必要指出这两个计划都包含一个指令:

    scoped="false"

    这意味着计划中的捆绑包可用于 user region 中的其他捆绑包。

    我们现在要做的就是启动计划。这是在配置文件夹中的 org.eclipse.virgo.kernel.userregion 属性文件中完成的。将以下行(粗体)添加到 initialArtifacts 部分:

    initialArtifacts = repository:plan/org.eclipse.virgo.kernel.userregion.blueprint,\
    repository:plan/org.jboss.netty,\
    repository:plan/com.apache.cassandra,\
    repository:plan/org.eclipse.equinox.security,\
    repository:plan/org.eclipse.jetty,\
    repository:plan/org.eclipse.rap,\

    repository:plan/org.eclipse.virgo.management

    重新启动应用程序服务器,管理控制台应该再次激活,但现在是通过 Jetty 服务器!

    以类似的方式,我们为 JaaS 安全、cassandra 客户端、netty 和 MySQL 客户端创建了用户区域。 Virgo 以这种方式允许很好的模块化和可维护性。

    运行应用程序

    最后,我们为每个应用程序包括了用户区域。如前所述,其中许多应用程序作为 RAP RCP 运行。最初我们认为我们可以只向用户区域添加计划来启动这些应用程序,但是当我们打开浏览器并浏览到 web 上下文 url 时,Jetty 告诉我们网页不可用。进一步的检查告诉我们,虽然所有包已正确启动并正在运行,我们的 RCP 应用程序不知何故无法通过声明性服务与 org.eclipse.rap.rwt.osgi 包建立连接,因此 RAP RWTServlet 未在 Jetty 的 servlet 容器中声明.

    在无数次失败的实验之后,我们通过使用网络上下文扩展 Manifest.MF 文件来“网络化”RAP 包:

    Web-ContextPath: /myapphomepage

    并添加一个带有 web.xml 文件的 WEB-INF 目录:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">

    <context-param>
    <param-name>org.eclipse.rap.applicationConfiguration</param-name>
    <param-value> com.mycompany.MyRapConfiguration </param-value>
    </context-param>

    <listener>
    <listener-class>org.eclipse.rap.rwt.engine.RWTServletContextListener</listener-class>
    </listener>

    <servlet>
    <servlet-name>rwtServlet</servlet-name>
    <servlet-class>org.eclipse.rap.rwt.engine.RWTServlet</servlet-class>
    </servlet>

    <servlet-mapping>
    <servlet-name>rwtServlet</servlet-name>
    <url-pattern> /myapphomepage </url-pattern>
    </servlet-mapping>
    </web-app>

    当我们构建 bundle 并将它们放到 pickup 目录中时(不是在计划中!),应用程序运行良好。

    结论

    我与 Virgo 应用程序服务器打交道确实让我对它的可能性充满热情,我相信我们真的可以通过简单地将捆绑包放入 Virgo 来激活我们的 OSGI 应用程序只是时间问题!如果你像我一样来自 OSGI 世界(而不是来自 Spring,例如),我相信当你想在 Virgo 应用服务器上部署多个应用程序时,上面描述的内核设置是你可以做的最干净的配置.如果我们设法省略 RAP 包的“网络化”,那么 Virgo 将真正成为 OSGI 应用程序的完美应用程序服务器!

    第二篇文章 中,我将更新上述配置。