[java] 매니페스트 파일의 메인 클래스가 아닌 Jar에서 클래스를 실행하는 방법

4 개의 클래스가있는 JAR이 있으며 각 클래스에는 Main 메서드가 있습니다. 필요에 따라 각각을 실행할 수 있기를 원합니다. 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

내 매니페스트 파일에서 하나의 클래스를 기본으로 지정할 수 있다는 것을 알고 있습니다. 그러나 명령 행에서 인수를 지정하여 실행하려는 클래스를 실행할 수있는 방법이 있습니까?

나는 이것을 시도했다 :

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’는 명령 행 인수입니다.



답변

매니페스트 파일에서 메인 클래스없이 항아리를 만들 수 있습니다. 그런 다음 :

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


답변

jar 파일에 정의 된 경우에도 JAR 파일 의 메소드 가있는 모든 클래스를 실행할 수 있습니다 .public final static mainMain-Class

메인 클래스 실행 :

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

public static void main메소드를 사용하여 다른 클래스를 실행하십시오 .

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

참고 : 첫 번째는 -jar, 두 번째는을 사용합니다 -cp.


답변

을 호출하는 것 외에도 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);

    }
}


답변

이 답변은 스프링 부트 사용자를위한 것입니다.

JAR이 Spring-boot프로젝트 에서 mvn package spring-boot:repackage왔고 명령을 사용하여 작성된 경우 위의 “-cp”메소드가 작동하지 않습니다. 당신은 얻을 것이다 :

오류 : 기본 클래스 your.alternative.class.path를 찾거나로드 할 수 없습니다.

에 의해 JAR의 클래스를 볼 수 있더라도 jar tvf yours.jar.

이 경우 다음 명령으로 대체 클래스를 실행하십시오.

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

내가 이해했듯이 Spring-boot의 org.springframework.boot.loader.PropertiesLauncher클래스는 디스패치 입구 클래스 역할을하며 -Dloader.main매개 변수는 실행할 클래스를 알려줍니다.

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


답변

우선 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 ...대신 시도해보십시오 . -cpjar를 클래스 경로에 설정하고 java가 기본 클래스를 조회 할 수있게합니다.


답변

주석에서 Nick이 간단히 언급 한 또 다른 비슷한 옵션은 여러 래퍼 항아리를 만드는 것입니다. 나는 그것을 시도하지는 않았지만 매니페스트 파일 이외의 완전히 비어있을 수 있다고 생각한다.이 클래스는로드 할 기본 클래스를 지정하고 MyJar.jar을 클래스 경로에 포함시켜야한다.

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

그런 다음 그냥 실행하십시오. java -jar MyJar2.jar


답변

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>