2017-03-31 27 views
0

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

我的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,它可以成功構建並生成目標文件夾中的.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 

如果這個問題,需要更多的信息,讓我知道。我在這裏不知所措。

+1

看這裏:http://stackoverflow.com/a/574650你需要maven-assembly-plugin,因爲在jar中只有你的類。 –

+0

爲什麼使用舊版本的Apache POI?爲什麼不是最新的? – Gagravarr

+0

謝謝所有人的迴應!我最終跟隨了Alex發送的鏈接並且到達了這個帖子:http://stackoverflow.com/questions/1814526/problem-building-executable-jar-with-maven這給了我需要的答案。 –

回答

1

你需要用Maven Assembly Plugin創建一個fat/uber jar。這意味着創建一個Jar和它的依賴Jars到一個可執行的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. 

你可以運行它follwoing;

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

您可以查看的內容日曆-1.0-快照與-dependencies.jar

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

的問題是,在編譯時POI庫也有,但不是在運行時。他們可用的原因是他們在Maven Dependency中。此外,我沒有看到任何生成包裝在您的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> 
0

Maven package任務只是將您項目的已編譯類打包到單個jar文件中。所有第三方庫都不包含在內,這就是爲什麼你會遇到錯誤 - 沒有找到POI類。

您應該建立一個包含所有依賴關係的可運行jar文件。請參閱this問題 - 您應該使用一些額外的maven插件來實現該目標。

1

您正在將maven工件打包爲jar,默認情況下,maven jar插件打包的jar不包含依賴jar建造神器。 而運行時丟失的類。

如果你想在你的jar中包含應用程序的依賴jar包,你應該使用maven assembly插件並且爲descriptorRef參數指定jar-with-dependencies

您可以將程序集目標執行綁定到程序包階段,以便您正在使用的執行實際上自動創建期望的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> 
相關問題