programing

매니페스트 파일의 기본 클래스가 아닌 Jar에서 클래스를 실행하는 방법

javaba 2022. 8. 12. 22:58
반응형

매니페스트 파일의 기본 클래스가 아닌 Jar에서 클래스를 실행하는 방법

저는 4개의 클래스가 있는 JAR을 가지고 있으며, 각각 메인 메서드를 가지고 있습니다.필요에 따라 그것들을 하나씩 실행할 수 있도록 하고 싶다.Linux 박스의 명령줄에서 실행하려고 합니다.

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

매니페스트 파일에서 하나의 클래스를 주(main)로 지정할 수 있습니다.그러나 명령줄에서 원하는 클래스를 실행하기 위한 인수를 지정할 수 있는 방법이 있습니까?

이거 해봤어요.

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' 및 '/home/myhome/input'이 사용됩니다.txt'는 명령줄 인수입니다).

Manifest 파일에 Main-Class 없이 항아리를 만들 수 있습니다.그 후, 다음과 같이 합니다.

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

다음 항목이 있는 모든 클래스를 실행할 수 있습니다.public final static mainJAR 파일에 정의된 메서드가 있는 경우에도 JAR 파일에서 메서드를 사용합니다.

메인 클래스 실행:

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

를 사용하여 다른 클래스 실행public static void main방법:

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

주의: 첫 번째 용도-jar, 두 번째 용도는-cp.

이 답변은 Spring-boot 사용자를 위한 것입니다.

JAR이 다음 버전부터Spring-boot프로젝트 및 명령어를 사용하여 작성mvn package spring-boot:repackage위의 "-cp" 메서드는 작동하지 않습니다.다음과 같은 이점을 얻을 수 있습니다.

오류: 주 클래스를 찾거나 로드할 수 없습니다.alternative.class를 선택합니다.경로.

JAR의 클래스를 표시할 수 있는 경우에도jar tvf yours.jar.

이 경우 다음 명령을 사용하여 대체 클래스를 실행합니다.

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

내가 이해한 바로는, 스프링 부츠는org.springframework.boot.loader.PropertiesLauncherclass는 디스패치 입학반으로 기능하며,-Dloader.mainparameter는 무엇을 실행할지 알려줍니다.

참고 자료: https://github.com/spring-projects/spring-boot/issues/20404

전화 말고도java -jar myjar.jar com.mycompany.Myclass매니페스트 클래스의 기본 클래스를 디스패처 클래스로 만들 수도 있습니다.

예:

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

    }
}

일단은jar는 항아리를 만들고 실행하지 않습니다.해라java -jar대신.

둘째, 왜 FQCN으로 2회 합격합니까?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가 클래스 패스의 메인클래스를 조회할 수 있도록 합니다.

Nick이 코멘트에서 간단히 언급했던 또 다른 유사한 옵션은 여러 개의 포장지 병을 만드는 것입니다.아직 시도하지 않았지만 manifest 파일 이외에는 완전히 비어 있을 수 있다고 생각합니다.manifest 파일에는 로드할 메인 클래스와 클래스 패스에 MyJar.jar가 포함되어 있습니다.

MyJar1.jar\META-INF\MANIFestMF

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

MyJar2.jar\META-INF\MANIFestMF

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

etc. etc와 . 그럼 그냥 실행해 주세요.java -jar MyJar2.jar

언급URL : https://stackoverflow.com/questions/5474666/how-to-run-a-class-from-jar-which-is-not-the-main-class-in-its-manifest-file

반응형