簡體   English   中英

在Maven項目中使用Apache POI運行.jar文件

[英]Running .jar file using Apache POI in Maven project

我正在努力運行一個使用Apache POI創建Excel文檔的簡單程序。 這也是我第一次參與Maven項目,因此可能與它有關:

我的pom.xml看起來像這樣:

<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/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>calendar</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>calendar</name>
  <url>http://maven.apache.org</url>

    <dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>

    <dependency>
          <groupId>org.apache.poi</groupId>
          <artifactId>poi</artifactId>
          <version>3.10-FINAL</version>
    </dependency>


    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.10-FINAL</version>
    </dependency>

  </dependencies>
</project>

據我所知,我的依賴關系還不錯。

這是我的Java代碼,我跳過了import語句,但是它們都在那里,根據我的判斷,此代碼中沒有錯誤:

public class App 
{

    private static final String FILE_NAME = "/tmp/MyFirstExcel.xlsx";

    public static void main( String[] args ) throws IOException
    {
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("Datatypes in Java");

        Object[][] datatypes = {
            {"Datatype", "Type", "Size(in bytes)"},
            {"int", "Primitive", 2},
            {"float", "Primitive", 4},
            {"double", "Primitive", 8},
            {"char", "Primitive", 1},
            {"String", "Non-Primitive", "No fixed size"}    
        };

        int rowNum = 0;
        System.out.println("Creating excel");
        for(Object[] datatype : datatypes) {
            Row row = sheet.createRow(rowNum++);
            int colNum = 0;
            for(Object field : datatype) {
                Cell cell = row.createCell(colNum++);
                if(field instanceof String) {
                    cell.setCellValue((String) field);
                }
                else if(field instanceof Integer) {
                    cell.setCellValue((Integer) field);
                }
            }
        }

        try {
            FileOutputStream outputStream = new FileOutputStream(FILE_NAME);
            workbook.write(outputStream);
            //workbook.close()
        } catch (FileNotFoundException e) {
            System.out.println("Couldn't find file to write out to");
        } catch (IOException e) {
            System.out.println("IO Exception in printing");
        }

    }
}

我已經注釋掉了workbook.close() ,因為這導致了錯誤(不建議使用的方法?)。

使用上面的代碼在我的源文件夾中,我可以運行mvn package ,該mvn package可以成功構建並在目標文件夾中生成.jar文件calendar-1.0-SNAPSHOT.jar

我正在嘗試使用運行此文件

java -cp target/calendar-1.0-SNAPSHOT.jar com.mycompany.app.App

...並且我收到以下錯誤消息

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/poi/ss/usermodel/Workbook
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
        at java.lang.Class.privateGetMethodRecursive(Unknown Source)
        at java.lang.Class.getMethod0(Unknown Source)
        at java.lang.Class.getMethod(Unknown Source)
        at sun.launcher.LauncherHelper.validateMainClass(Unknown Source)
        at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.apache.poi.ss.usermodel.Workbook
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 7 more

如果這個問題需要更多信息,請告訴我。 我在這里茫然。

您需要使用Maven Assembly Plugin創建一個胖子/超級瓶子。 這意味着將一個Jar及其依賴的Jar一起創建到一個可執行的Jar文件中。 當您運行它時,它將具有所有可用的依賴項。

在您的POM中添加以下插件

<build>
    <plugins>
        <!-- Maven Assembly Plugin -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.4.1</version>
            <configuration>
                <!-- get all project dependencies -->
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <!-- MainClass in mainfest make a executable jar -->
                <archive>
                  <manifest>
                    <mainClass>com.your.path.to.main.App</mainClass>
                  </manifest>
                </archive>

            </configuration>
            <executions>
              <execution>
                <id>make-assembly</id>
                                    <!-- bind to the packaging phase -->
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
              </execution>
            </executions>
        </plugin>

    </plugins>
</build>

運行以下命令:

mvn package

將在目標文件夾中創建兩個jar文件。

calendar-1.0-SNAPSHOT.jar – Only your project classes
calendar-1.0-SNAPSHOT-with-dependencies.jar – Project and dependency classes in a single jar.

您可以按照以下方式運行它;

java -cp target/calendar-1.0-SNAPSHOT-with-dependencies.jarcom.mycompany.app.App

您可以查看calendar-1.0-SNAPSHOT-with-dependencies.jar的內容

jar tf target/calendar-1.0-SNAPSHOT-with-dependencies.jar

您將maven工件打包為jar,並且默認情況下,由maven jar插件打包的jar不包含帶有已構建工件的依賴項jar。 而運行時缺少的類。

如果要在jar中包含應用程序的依賴jar,則應使用maven程序集插件,並為描述符ref參數指定jar-with-dependencies

您可以將程序集的single目標執行綁定到程序包階段,以便您正在使用的mvn package執行實際上自動創建預期的jar。

<plugins>
  <plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
      <archive>
        <manifest>
          <mainClass>YourMainClassPrefixedByItsPackage</mainClass>
        </manifest>
      </archive>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
    </configuration>
    <executions>
      <execution>
        <id>make-assembly</id> 
        <phase>package</phase> <!-- bind to the packaging phase -->
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

問題是在編譯時POI庫可用,但在運行時不可用。 它們可用的原因是它們處於Maven依賴關系中。 另外,我在pom文件中看不到任何構建包裝器。 您將需要添加構建包裝器來構建可以在IDE外部運行的jar文件。

現在回到您的問題,您需要在CLASSPATH環境變量中添加POI jar,以便Java運行時可以訪問它或構建包含依賴項的胖jar。

您可以使用此模板在pom文件中添加構建包裝器,以構建具有依賴項的jar。

<build>
    <plugins>
      <plugin>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
          <execution>
            <phase>install</phase>
            <goals>
              <goal>copy-dependencies</goal>
            </goals>
            <configuration>
              <outputDirectory>${project.build.directory}/lib</outputDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

Maven package任務只是將項目的已編譯類打包到單個jar文件中。 所有第三方庫均未包括在內,這就是為什么您會報錯-未找到POI類。

您應該構建一個包含所有依賴項的可運行jar文件。 請參考這個問題-您應該使用一些其他的Maven插件來實現這一目標

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM