Manifest dosyasında Main-Class olmayan Jar'dan bir sınıf nasıl çalıştırılır


166

4 Sınıf bir JAR var, her biri ana yöntemi vardır. Bunların her birini ihtiyaca göre çalıştırabilmek istiyorum. Linux kutusunda komut satırından çalıştırmaya çalışıyorum.

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

Aşağıdaki gibi ana sınıflar için dizin yapısına sahiptir:

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

Manifest dosyamda ana olarak bir sınıf belirtebileceğimi biliyorum. Ama hangi sınıfta çalıştırmak isterseniz çalıştırmak için komut satırında bazı argüman belirtebileceğim bir yol var mı?

Bunu denedim:

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

Ve bu hatayı aldım:

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

(Yukarıdaki komutta, '/home/myhome/datasource.properties' ve '/home/myhome/input.txt' komut satırı bağımsız değişkenleridir).


Bağımlılıkları tutmak için başka bir kavanoz kullanarak onları farklı kavanozlara paketleyin mi?
Nick

11
Neden komut satırı bağımsız değişkenlerine dayalı olarak belirli yöntemi (4'ten) çağıran tek bir ana sınıfınız olmasın?
Can not Tell

Yanıtlar:


216

Kavanozu, Manifest dosyasında Main-Class olmadan oluşturabilirsiniz. Sonra :

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

2
Dokümana göre bu işe yaramayacak: "Bu seçeneğin çalışması için JAR dosyasının manifest'i Main-Class: classname biçiminde bir satır içermelidir."
Thomas

"Main-Class manifest özelliği MyJar.jar'dan yüklenemedi"
Bhushan

10
Thomas haklı. "-jar" yerine "-cp" yazmanız gerekir. Güncellenmiş kodumu görüntüle
lxu4net

9
@Chrisdew tarafından sağlanan cevap, Main-Class özniteliğini değiştirerek / kaldırarak Jar dosyasını değiştirmek zorunda kalmadan çalışır.
Ed Griebel

155

Jar dosyası tanımlı olsa bile , bir JAR dosyasından yöntemi olan herhangi bir sınıfı yürütebilirsiniz .public final static mainMain-Class

Ana Sınıfı Yürüt:

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

Bir public static void mainyöntemle başka bir sınıf yürütün :

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

Not: ilk kullanımlar -jar, ikinci kullanımlar -cp.


10
Eğer çok üzerinde sınıf geçerli dizindeki tüm kavanozları (örn. Lib dizinindeki Ana sınıfından çalıştıran) ve istediğin kullanabilirsiniz java -cp "./*" com.mycomp.myproj.AnotherClassWithMainMethodetrafında çift tırnak Not ./*onu genişlemesini Unix makineleri önlenmesi. Ayrıca "./*.jar"işe yaramayacağını unutmayın .
Petr Újezdský

19

Arama dışında, java -jar myjar.jar com.mycompany.MyclassManifest'inizdeki ana sınıfı bir Dispatcher sınıfınız da yapabilirsiniz.

Misal:

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);

    }
}

1
Bu, bunu yapmanın iyi bir alternatif yoludur! Kavanozum "spring-boot: repackage" kullanılarak oluşturuldu, bu yüzden diğer giriş sınıflarını "-cp" yolu ile çalıştıramıyorum. Spring-boot eklentisinin kavanoza ne yaptığını bilmiyorum. Bu durumda, bir sevk sınıfı yardımcı olur.
Zhou

6

Bu cevap Spring-boot kullanıcıları içindir:

Lütfen JAR bir den idiyse Spring-bootproje ve komut kullanılarak oluşturulan mvn package spring-boot:repackage, yukarıdaki "cp" yöntemi işi olmaz. Alacaksın:

Hata: Ana sınıf your.alternative.class.path bulunamadı veya yüklenemedi

Sınıfı JAR'da görebilseniz bile jar tvf yours.jar.

Bu durumda, alternatif sınıfınızı aşağıdaki komutla çalıştırın:

java -cp yours.jar -Dloader.main=your.alternative.class.path org.springframework.boot.loader.PropertiesLauncher

Anladığım kadarıyla, Spring-boot'ın org.springframework.boot.loader.PropertiesLaunchersınıfı gönderici bir giriş sınıfı olarak hizmet ediyor ve -Dloader.mainparametre ona ne çalıştırılacağını söylüyor.

Referans: https://github.com/spring-projects/spring-boot/issues/20404


Ya kavanozunuz yürütülebilirse. yani kavanozu açtığınızda tüm sınıflardan önce "/ BOOT-INF / classes /" gelir
slashdottir

2

Her şeyden önce jarbir kavanoz oluşturur ve onu çalıştırmaz. java -jarBunun yerine deneyin .

İkincisi, sınıfı neden FQCN ( com.mycomp.myproj.dir2.MainClass2) ve file ( com/mycomp/myproj/dir2/MainClass2.class) olarak iki kez iletiyorsunuz ?

Düzenle:

java -jarBir ana sınıfın belirtilmesini gerektiriyor gibi görünüyor . Bunun java -cp your.jar com.mycomp.myproj.dir2.MainClass2 ...yerine deneyebilirsiniz . -cpkavanozu sınıf yoluna yerleştirir ve java'nın ana sınıfı orada aramasını sağlar.



1
Bu sayfadan: "Bir jar dosyası oluşturulurken veya güncellenirken kullanılabilir." - Bu, kavanozu çalıştırmak için değil, ana sınıf niteliğini ayarlamak için kullanılır.
Thomas

1

Nick'in yorumlarda kısaca bahsettiğini düşündüğüm başka bir benzer seçenek, çoklu sargı kavanozları yaratmak. Ben denemedim, ama yük için ana sınıfı yanı sıra MyJar.jar sınıf yoluna dahil belirtilmesi gereken manifest dosya dışında tamamen boş olabilir düşünüyorum.

MyJar 1 .jar \ META-INF \ MANIFEST.MF

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

MyJar 2 .jar \ META-INF \ MANIFEST.MF

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

Sonra sadece ile çalıştırın java -jar MyJar2.jar


-4

Pom.xml dosyanıza aşağıdaki eklentiyi ekleyin ve elementte tam adı olan Ana Sınıfı belirtin.

<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>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.