【问题标题】:Cannot find class from jar in maven plugin在 Maven 插件中无法从 jar 中找到类
【发布时间】:2011-08-26 07:33:39
【问题描述】:

我正在制作一个 Maven 插件来启动、停止和清除数据库。我正在使用 hsqldb。我有一个类(称为 ServerStart)来启动数据库:

import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.hsqldb.Server;
import org.hsqldb.util.SqlFile;

public static void main(String[] args) {

    System.out.println("Starting server...");
    createServer();

    try {
        createADatabase(dbName);
        System.out.println("Server started!");

    } catch (Exception e) {
        e.printStackTrace();
    }
}

当我在 Eclipse 中运行主类(右键单击并作为 JavaApplication 运行)时,它可以工作。但是当我尝试使用我的 mvn 命令从 cmd 行运行它时,我得到了这个错误:

Exception in thread "main" java.lang.NoClassDefFoundError: org/hsqldb/Server
at sample.plugin.hello_maven_plugin.ServerStart.createServer(ServerStart
.java:50)
at sample.plugin.hello_maven_plugin.ServerStart.main(ServerStart.java:37)
Caused by: java.lang.ClassNotFoundException: org.hsqldb.Server
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
... 2 more

当我运行 mvn 命令时,他尝试通过以下方式从外部启动 ServerClass:

startOptions = new String[] {"java", "-cp", System.getProperty("user.dir") + "/target/classes/", ServerStart.class.getName()};
new ProcessBuilder(startOptions).start();

我想我忘了在我的 pom.xml 文件中添加一些内容,所以他包含了 hsqldb.jar,但我不知道是什么。这是我的 pom 文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>sample.plugin</groupId>
<artifactId>hsqldb-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging>

<name>hsqldb-maven-plugin</name>
<url>http://maven.apache.org</url>

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>3.8.1</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-plugin-api</artifactId>
    <version>3.0.3</version>
  </dependency>
  <dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.4</version>
  </dependency>

  <dependency>
    <groupId>hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
    <version>1.8.0.10</version>
  </dependency>
</dependencies>  



<build>
  <plugins>
      <plugin>
          <groupId>sample.plugin</groupId>
          <artifactId>hsqldb-maven-plugin</artifactId>
          <version>1.0-SNAPSHOT</version>         
      </plugin>  
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
            <source>1.6</source>
            <target>1.6</target>
        </configuration>
      </plugin>    
  </plugins>
</build>

</project>

希望我的问题够清楚,也希望有人能帮助我。

亲切的问候,

华尔

【问题讨论】:

    标签: java jar maven-plugin hsqldb pom.xml


    【解决方案1】:

    a) ???你定义插件:

    <groupId>sample.plugin</groupId>
    <artifactId>hsqldb-maven-plugin</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>maven-plugin</packaging>
    

    并在构建部分将自身作为插件引用?

    <plugin>
        <groupId>sample.plugin</groupId>
        <artifactId>hsqldb-maven-plugin</artifactId>
        <version>1.0-SNAPSHOT</version>         
    </plugin>
    

    这不是它的工作原理!插件是为其他项目设计的,而不是为自己设计的!

    b)

    startOptions = new String[] {"java", "-cp", System.getProperty("user.dir") + "/target/classes/", ServerStart.class.getName()};
    new ProcessBuilder(startOptions).start();
    

    在你的类路径中你需要的不仅仅是目标/类。获得正确类路径的最简单方法是 let Maven build it for you:

    <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-dependency-plugin</artifactId>
       <version>2.2</version>
       <executions>
         <execution>
            <id>build-test-classpath</id>
            <phase>generate-test-sources</phase>
            <goals>
              <goal>build-classpath</goal>
            </goals>
            <configuration>
              <outputFile>${project.build.testOutputDirectory}/cp.txt</outputFile>
            </configuration>
         </execution>
       </executions>
    </plugin>
    

    现在您会在测试类路径中找到一个名为 cp.txt 的文件,其中包含您需要的类路径。或者,您可以只使用System.getProperty("java.class.path") 的内容。

    【讨论】:

    • 插件中找不到build-test-classpath。
    • @Walle,对不起,混淆了 id 和目标。现已修复
    • 我在该文本文档中看到很多 .jar 文件,还有缺少的 hsqldb.jar。如果我使用System.getProperty("java.class.path"),他会包含所有打印在该文本文件中的 .jar 文件吗?因为我已经尝试过了,但是没有用。也许我做错了什么。
    • 另外,当我 system.out.println System.getProperty("java.class.path") 我只看到一个 .jar 文件。这正常吗?
    • 你在使用m2eclipse吗?如果你是,eclipse 应该知道 maven 类路径和 java.class.path 应该工作
    【解决方案2】:

    您的 hsqldb 依赖项中的 groupId 错误。我有同样的问题。使用以下依赖修复它。

        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <version>2.0.0</version>
        </dependency>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-27
      • 2016-04-17
      • 1970-01-01
      • 2012-01-04
      相关资源
      最近更新 更多