简体   繁体   English

Maven AppAssembler没有找到课程

[英]Maven AppAssembler not finding class

Attempting to modify an existing Java/Tomcat app for deployment on Heroku following their tutorial and running into some issues with AppAssembler not finding the entry class. 尝试修改现有的Java / Tomcat应用程序,以便在他们的教程之后在Heroku上进行部署,并遇到AppAssembler未找到入门类的一些问题。 Running target/bin/webapp (or deploying to Heroku) results in Error: Could not find or load main class org.stopbadware.dsp.Main 运行目标/ bin / webapp(或部署到Heroku)会导致Error: Could not find or load main class org.stopbadware.dsp.Main

Executing java -cp target/classes:target/dependency/* org.stopbadware.dsp.Main runs properly however. 执行java -cp target/classes:target/dependency/* org.stopbadware.dsp.Main然而正常运行。 Here's the relevant portion of pom.xml: 这是pom.xml的相关部分:

  <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>appassembler-maven-plugin</artifactId>
      <version>1.1.1</version>
      <configuration>
          <assembleDirectory>target</assembleDirectory>
          <programs>
              <program>
                  <mainClass>org.stopbadware.dsp.Main</mainClass>
                  <name>webapp</name>
              </program>
          </programs>
      </configuration>
      <executions>
          <execution>
              <phase>package</phase>
              <goals>
                  <goal>assemble</goal>
              </goals>
          </execution>
      </executions>
    </plugin>

My guess is mvn package is causing AppAssembler to not use the correct classpath, any suggestions? 我的猜测是mvn package导致AppAssembler没有使用正确的类路径,有什么建议吗?

Your artifact's packaging must be set to jar , otherwise the main class is not found. 您的工件包装必须设置为jar ,否则找不到主类。

<pom>
  ...
  <packaging>jar</packaging>
  ...
</pom>

The artifact itself is added at the end of the classpath, so nothing other than a JAR file will have any effect. 工件本身是在类路径的末尾添加的,因此除了JAR文件之外什么都不会产生任何影响。

尝试:

mvn clean package jar:jar appassembler:assemble

The first thing is that you are using an old version of appassembler-maven-plugin the current version is 1.3. 首先,您使用的是旧版本的appassembler-maven-plugin ,当前版本为1.3。

What i don't understand why are you defining the 我不明白为什么你要定义

<assembleDirectory>target</assembleDirectory>

folder. 夹。 There exists a good default value for that. 这有一个很好的默认值。 So usually you don't need it. 所以通常你不需要它。 Apart from that you don't need to define an explicit execution which bounds to the package phase, cause the appassembler-maven-plugin is by default bound to the package phase . 除此之外,您不需要定义绑定到包阶段的显式执行,因此默认情况下appassembler-maven-plugin绑定到包阶段

Furthermore you can use the useWildcardClassPath configuration option to make your classpath shorter. 此外,您可以使用useWildcardClassPath配置选项来缩短类路径。

   <configuration>
     <useWildcardClassPath>true</useWildcardClassPath>
     <repositoryLayout>flat</repositoryLayout>
     ...
   </configruation>

And that the calling of the generated script shows the error is depending on the thing that the location of the repository where all the dependencies are located in the folder is different than in the generated script defined. 并且调用生成的脚本显示错误取决于文件夹中所有依赖项所在的存储库位置与定义的生成脚本中的位置不同。

Was able to solve this by adding "$BASEDIR"/classes to the CLASSPATH line in the generated script. 能够通过在生成的脚本中将"$BASEDIR"/classes到CLASSPATH行来解决此问题。 Since the script gets rewritten on each call of mvn package I wrote a short script that calls mvn package and then adds the needed classpath entry. 由于脚本在每次调用mvn package都被重写,我编写了一个调用mvn package的短脚本,然后添加了所需的类路径条目。

Obviously a bit of a hack but after a 8+ hours of attempting a more "proper" solution this will have to do for now. 显然有点像黑客,但经过8个多小时的尝试更“正确”的解决方案,这将是现在必须做的。 Will certainly entertain any more elegant ways of correcting the classpath suggested here. 肯定会采用任何更优雅的方式来纠正这里建议的类路径。

You can set the CLASSPATH_PREFIX environment variable: 您可以设置CLASSPATH_PREFIX环境变量:

export CLASSPATH_PREFIX=target/classes

which will get prepended to the classpath of the generated script. 它将被添加到生成的脚本的类路径中。

I was going through that tutorial some time ago and had very similar issue. 我前段时间正在阅读该教程,并且遇到了非常类似的问题。 I came with a bit different approach which works for me very nicely. 我带来了一个不同的方法,非常适合我。

First of all, as it was mentioned before, you need to keep your POM's type as jar ( <packaging>jar</packaging> ) - thanks to that, appassembler plugin will generate a JAR file from your classes and add it to the classpath. 首先,正如之前提到的,你需要将你的POM类型保存为jar<packaging>jar</packaging> ) - 多亏了这一点, appassembler插件将从你的类生成一个JAR文件并将其添加到类路径。 So thanks to that your error will go away. 所以,多亏了你的错误就会消失。

Please note that this tutorial Tomcat is instantiated from application source directory. 请注意,本教程Tomcat是从应用程序源目录实例化的。 In many cases that is enough, but please note that using that approach, you will not be able to utilize Servlet @WebServlet annotations as /WEB-INF/classes in sources is empty and Tomcat will not be able to scan your servlet classes. 在许多情况下这已足够,但请注意,使用该方法,您将无法使用Servlet @WebServlet注释,因为源中的/WEB-INF/classes为空,Tomcat将无法扫描您的servlet类。 So HelloServlet servlet from that tutorial will not work, unless you add some additional Tomcat initialization (resource configuration) as described here (BTW, you will find more SO questions talking about that resource configuration). 因此,除非您按照此处所述添加一些额外的Tomcat初始化(资源配置),否则该教程中的HelloServlet servlet将无法工作(顺便说一下,您会发现更多关于该资源配置的SO问题)。

I did a bit different approach: 我采取了一些不同的方法:

I run a org.apache.maven.plugins:maven-war-plugin plugin ( exploded goal) during package and use that generated directory as my source directory of application. 我在package期间运行了一个org.apache.maven.plugins:maven-war-plugin插件( exploded目标)并使用该生成的目录作为我的应用程序源目录。 With that approach my web application directory will have /WEB-INF/classes "populated" with classes. 使用这种方法,我的Web应用程序目录将使用/WEB-INF/classes “填充” /WEB-INF/classes classes。 That in turn will allow Tomcat to perform scanning job correctly (ie Servlet @WebServlet annotations will work). 这反过来将允许Tomcat正确执行扫描作业(即Servlet @WebServlet注释将起作用)。

I also had to change a source of my application in the launcher class: 我还必须在启动器类中更改我的应用程序的源:

public static void main(String[] args) throws Exception {
    // Web application is generated in directory name as specified in build/finalName
    // in maven pom.xml
    String webappDirLocation = "target/embeddedTomcatSample/";
    Tomcat tomcat = new Tomcat();

    // ... remaining code does not change

Changes to POM which I added - included maven-war-plugin just before appassembler plugin: 我添加的对POM的更改 - 包括在appassembler插件之前的maven-war-plugin plugin:

...
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.5</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>exploded</goal>
            </goals>
        </execution>
    </executions>
</plugin>
...

Please note that exploded goal is called. 请注意,会调用exploded目标。

I hope that small change will help you. 我希望小改变能帮到你。


One more comment on that tutorial and maven build: note that the tutorial was written to show how simple is to build an application and run it in Heroku. 关于该教程和maven构建的另外一条评论:请注意,编写本教程是为了说明构建应用程序并在Heroku中运行它是多么简单。 However, that is not the best approach to maven build. 但是,这不是maven构建的最佳方法。

Maven recommendation is that you should adhere to producing one artifact per POM. Maven的建议是你应该坚持每个POM生成一个工件。 In your case there are should two artifacts: 在你的情况下,应该有两个工件:

  • Tomcat launcher Tomcat发射器
  • Tomcat web application Tomcat Web应用程序

Both should be build as separate POMs and referenced as modules from your parent POM. 两者都应该构建为单独的POM,并作为父POM中的模块引用。 If you look at the complexity of that tutorial, it does not make much sense to split that into two modules. 如果你看一下该教程的复杂性,将它分成两个模块没有多大意义。 But if your applications gets more and more complex (and the launcher gets some additional configurations etc.) it will makes a lot of sense to make that "split". 但是如果你的应用程序变得越来越复杂(并且启动器获得了一些额外的配置等),那么进行“拆分”将会很有意义。 As a matter of fact, there are some "Tomcat launcher" libraries already created so alternatively you could use of one them. 事实上,已经创建了一些“Tomcat启动程序”库,所以您也可以使用它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 通过appassembler-maven-plugin生成的脚本无法在Spring Boot应用程序中找到主类 - Script generated via appassembler-maven-plugin is not able to find main class in Spring Boot application 在Appassembler中更改类路径-Maven插件 - change classpath in Appassembler - Maven Plug-In appassembler-maven-plugin将自定义条目添加到类路径 - appassembler-maven-plugin add custom entry to classpath 如何使Maven Appassembler在生成的脚本中使用Javaw而不是Java - How to make maven appassembler use javaw instead of java in generated scripts 错误的solaris-sparc-64的Maven Appassembler生成守护程序 - Error maven appassembler generate-daemons for solaris-sparc-64 Maven Appassembler插件:启动程序之前更改当前目录 - Maven appassembler plugin: change current directory before launching program Maven没有从测试套件类中找到测试 - Maven not finding tests from a test suite class tanukisoft守护程序包装程序和Appassembler Maven插件-如何解决冲突的jar名称? - tanukisoft daemon wrapper and appassembler maven plugin - how to resolve conflicting jar names? 在appassembler-maven-plugin之后如何压缩和部署dist工件 - How to zip and deploy a dist artefact after appassembler-maven-plugin:assemble maven-jar-plugin找不到我的主要课程 - maven-jar-plugin not finding my main class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM