且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

错误找不到或加载主类

更新时间:2022-05-10 06:28:51

使用Jetty可以执行自执行的WAR,但是设置起来有些棘手,因为各种Maven插件都倾向于撤消自执行WAR的工作.

A self executing WAR with Jetty is possible, however its a bit tricky to setup, as the various maven plugins tend to undo the efforts of a Self Executing WAR.

Jetty项目维护着一个示例项目.

The Jetty Project maintains such an example project.

https://github.com/jetty-project/embedded-jetty-实战

关键是它的组装方式.

该项目包含4个主要部分:

The project has 4 main parts:

  • /thewebapp/-这是WAR文件,即webapp,它以其原始格式存在,具有正常的maven战争,并且产生的工件仅是尚未(尚未)自执行的WAR文件. /li>
  • /theserver/-这是嵌入式Jetty服务器jetty.livewar.ServerMain.main(String args[]),您可以对其进行自定义以初始化Jetty服务器及其WebApp.您还可以在该项目中自定义JDBC服务器库,JNDI,日志记录等内容.此项目将生成一个uber-jar,其中包含运行服务器所需的所有依赖项.使用maven-shade-plugin来合并META-INF/services/文件时要格外小心.
  • /server-bootstrap/-包含2个小类,这些小类根据实时WAR中的内容设置LiveWarClassLoader,然后从此新的ClassLoader运行jetty.livewar.ServerMain.main(String args[]).该项目还包含实时WAR需要/使用的实时META-INF/MANIFEST.MF
  • /livewar-assembly/-这是将上述3个项目链接到一个Live/Executable WAR文件中的项目.来自上述3个项目的工件由maven-assembly-plugin拆包,并放置在它们将发挥最大作用(且安全)的位置.例如,将/theserver/中的服务器类放置在/WEB-INF/jetty-server/中,以使访问WAR文件的Web客户端无法访问它们.
  • /thewebapp/ - this is the WAR file, the webapp, as it exists in its native format, with normal maven war and a produced artifact that is just a WAR file that isn't (yet) self-executing.
  • /theserver/ - this is the Embedded Jetty Server jetty.livewar.ServerMain.main(String args[]) which you customize to initialize your Jetty server and its WebApp. This project also is the place where you customize for things like JDBC servers libraries, JNDI, logging, etc. This project produces a uber-jar with all of the dependencies needed to run the server. Special care is taken with the maven-shade-plugin to merge META-INF/services/ files.
  • /server-bootstrap/ - this contains 2 small classes that sets up a LiveWarClassLoader from the content in the live WAR and then runs jetty.livewar.ServerMain.main(String args[]) from this new ClassLoader. This project also contains the live META-INF/MANIFEST.MF that the live WAR will need/use
  • /livewar-assembly/ - this is the project that ties together the above 3 projects into a Live/Executable WAR file. The artifacts from from the above 3 projects are unpacked by the maven-assembly-plugin and put into place where they will be most functional (and safe). For example, the server classes from /theserver/ are placed in /WEB-INF/jetty-server/ to make them inaccessible from Web Clients accessing the WAR file.

注意:新组装的WAR文件中应该存在3个文件,如果使用此设置,则Web客户端可以将这些文件作为静态内容下载.

Note: there are 3 files present in your new assembled WAR file that you should be aware of, as these files can be downloaded by a Web Client as static content if you use this setup.

/jetty/bootstrap/JettyBootstrap.class
/jetty/bootstrap/LiveWarClassLoader.class
/META-INF/MANIFEST.MF

示例项目的设置方式应确保这些引导文件中存在的信息不应泄露有关您的服务器或其操作的私人或敏感信息.仅仅是Webapp可以作为实时/可执行WAR文件启动.

The example project is setup in such a way that information present in these bootstrap files should not reveal private or sensitive information about your Server or its operations. Merely that the Webapp can be started as a Live/Executable WAR file.

有4个模块产生1个可执行工件可能看起来很奇怪,但是您必须了解要处理3件事情才能设置此环境.

It might seem strange to have 4 modules result in 1 executable artifact, but you have to understand you are dealing with 3 things to set this environment up.

  1. WebApp本身(及其所有类和jar)-这是/thewebapp/
  2. 代表服务器主体的类及其要求. (不要与WebApp类混合在一起)-这是/theserver/
  3. Main-Class可执行文件,将上述2种智能地绑定在一起(以免给自己造成安全问题)-这是/server-bootstrap/
  1. The WebApp itself (with all of its classes and jars) - this is /thewebapp/
  2. The Classes representing the Server Main, and its requirements. (not to be co-mingled with the WebApp classes) - this is /theserver/
  3. The Main-Class executable that binds the above 2 together intelligently (so as to not create a security issue for yourself) - this is /server-bootstrap/

最后一个模块/livewar-assembly/只是将3个部分捆绑为一个统一的整体.

The final module, /livewar-assembly/ just ties together the 3 parts into a unified whole.

我知道可能全部使用maven-shade-plugin可能很诱人,但是您将无法满足以下所有要求(您可以满足其中一些要求,然后尝试为其他要求解决,但最终打破别人,玩无休止的古怪游戏)...

I know it might be tempting to use maven-shade-plugin for it all, but you will not be able to accomplish all of the following requirements (you can accomplish some of them, and then attempt to fix for the others, but ultimately break the others, playing an endless game of wack-a-mole) ...

  1. 将服务器jar放置在无法通过Live WebApp访问的位置.
  2. 智能地合并服务器端(并且仅限服务器端)META-INF/services.
  3. 将BootStrap类添加到WAR的根中.
  4. 使用用于引导程序的自定义META-INF/MANIFEST.MF(也不会从所有服务器依赖项中获取META-INF/MANIFEST.MF文件的合并副本)
  1. Placing the Server jars in a place where they cannot be accessed via the Live WebApp.
  2. Merging Server side (and ONLY the server side) META-INF/services intelligently.
  3. Adding the BootStrap classes to the root of the WAR.
  4. Using a custom META-INF/MANIFEST.MF meant for the bootstrap (without also getting a merged copy of the META-INF/MANIFEST.MF files from all of the Server dependencies)