2011-03-29 17 views
80

我有一個帶有4個類的JAR,每個類都有Main方法。我希望能夠根據需要運行其中的每一個。我試圖從Linux上的命令行中運行它。如何從Jar中運行一個不是它的Manifest文件中的Main-Class的類

E.g. The name of my JAR is MyJar.jar 

它的主要類別如下目錄結構:

com/mycomp/myproj/dir1/MainClass1.class 
com/mycomp/myproj/dir2/MainClass2.class 
com/mycomp/myproj/dir3/MainClass3.class 
com/mycomp/myproj/dir4/MainClass4.class 

我知道我可以在我的清單文件指定一個類爲主。但是,有什麼方法可以在命令行上指定一些參數來運行我希望運行的任何類?

我嘗試這樣做:

jar cfe MyJar.jar com.mycomp.myproj.dir2.MainClass2 com/mycomp/myproj/dir2/MainClass2.class /home/myhome/datasource.properties /home/myhome/input.txt 

而且我得到了這個錯誤:

com/mycomp/myproj/dir2/MainClass2.class : no such file or directory 

(在上面的命令, '/home/myhome/datasource.properties' 和「/家庭/ MYHOME /input.txt'是命令行參數)。

+0

只需將它們打包到不同的罐子中,使用另一個jar來保存依賴關係? – Nick 2011-03-29 15:05:22

+6

爲什麼不能有基於命令行參數調用具體的方法(從4)單主類? – 2011-03-29 15:05:53

回答

111

您可以在其Manifest文件中創建沒有Main-Class的jar。然後:

java -cp MyJar.jar com.mycomp.myproj.dir2.MainClass2 /home/myhome/datasource.properties /home/myhome/input.txt 
+2

根據商務部這是行不通的:「爲了讓這個選項工作,JAR文件的清單必須包含線形式的Main-Class的:類名」 – Thomas 2011-03-29 15:13:18

+0

「無法加載主類清單屬性來自MyJar.jar「 – Bhushan 2011-03-29 15:25:55

+2

托馬斯是對的。你需要用「-cp」替換「-jar」。看到我更新的代碼 – lxu4net 2011-03-30 02:05:31

2

首先jar創建一個jar,並不運行它。改爲嘗試java -jar。第二,你爲什麼通過這個班級兩次,如FQCN(com.mycomp.myproj.dir2.MainClass2)和檔案(com/mycomp/myproj/dir2/MainClass2.class)?

編輯:

看起來好像java -jar需要指定一個主類。您可以嘗試使用java -cp your.jar com.mycomp.myproj.dir2.MainClass2 ...-cp在類路徑上設置jar,並使java能夠在那裏查找主類。

+0

我沒有這裏提到:http://download.oracle.com/javase/tutorial/deployment/jar/appman.html – Bhushan 2011-03-29 15:08:58

+0

在這個頁面:「這可以在創建或更新一個jar文件中使用」 - 所以這被用來設置主類的屬性,而不是運行jar。 – Thomas 2011-03-29 15:11:15

8

除了呼籲java -jar myjar.jar com.mycompany.Myclass,還可以使你的清單一個Dispatcher類的主類。

例子:

public class Dispatcher{ 

    private static final Map<String, Class<?>> ENTRY_POINTS = 
     new HashMap<String, Class<?>>(); 
    static{ 
     ENTRY_POINTS.put("foo", Foo.class); 
     ENTRY_POINTS.put("bar", Bar.class); 
     ENTRY_POINTS.put("baz", Baz.class); 
    } 

    public static void main(final String[] args) throws Exception{ 

     if(args.length < 1){ 
      // throw exception, not enough args 
     } 
     final Class<?> entryPoint = ENTRY_POINTS.get(args[0]); 
     if(entryPoint==null){ 
      // throw exception, entry point doesn't exist 
     } 
     final String[] argsCopy = 
      args.length > 1 
       ? Arrays.copyOfRange(args, 1, args.length) 
       : new String[0]; 
     entryPoint.getMethod("main", String[].class).invoke(null, 
      (Object) argsCopy); 

    } 
} 
0

,我認爲尼克簡短的評論提到的另一個類似的選項是創建多個包裝罐。我沒有嘗試過,但我認爲它們可能完全是空的,除了清單文件以外,它應該指定加載的主類以及將MyJar.jar包含到類路徑中。

myjar這一的.jar \ META-INF \ MANIFEST.MF

Manifest-Version: 1.0 
Main-Class: com.mycomp.myproj.dir1.MainClass1 
Class-Path: MyJar.jar 

myjar這一的.jar \ META-INF \ MANIFEST.MF

Manifest-Version: 1.0 
Main-Class: com.mycomp.myproj.dir2.MainClass2 
Class-Path: MyJar.jar 

等 然後只需用java -jar MyJar2.jar

67

運行它,你可以執行任何具有從一個JAR文件中的public final static main方法,即使jar文件有Main-Class定義

執行主類:

java -jar MyJar.jar // will execute the Main-Class 

執行另一個類與public static void main方法:

java -cp MyJar.jar com.mycomp.myproj.AnotherClassWithMainMethod 

注意:第一個使用-jar,第二個使用-cp

+4

如果你想在類路徑在當前目錄下的所有jar文件太多(如運行從lib目錄主類),你可以用'java命令「./*」 com.mycomp.myproj.AnotherClassWithMainMethod' 注意雙引號' ./*'防止unix機器擴展它。還要注意''./*。jar「'不起作用。 – 2016-06-16 09:05:54

1

下面添加插件,在pom.xml文件,並與元素全名來指定主類。

<plugin> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-maven-plugin</artifactId> 
    <version>1.2.5.RELEASE</version> 
    <configuration> 
     <mainClass>**main Class name with full qualified name**</mainClass> 
    </configuration> 
    <executions> 
     <execution> 
      <goals> 
       <goal>repackage</goal> 
      </goals> 
     </execution> 
    </executions> 
</plugin> 
相關問題