Does the JAR entry point really need to be inside the JAR?

A bit of context

I am trying to create a minimal framework using a launcher that will be common across multiple projects. However, I am running into difficulties when it comes to running JARs.

My goal is to have a self-contained command java -jar

: MANIFEST knows the classpath and entry point. The delicate bit is this: since I want the launcher to be common across all projects and be DRY compliant, I have a specific JAR with it that will always be in the classpath.

Now I am having problems starting my jar:

java -jar test.jar

should load the classpath and entry point from the manifest. He finds a manifesto, but I finish Could not find or load main class

.

Running more details works:

java -cp test.jar; lib / * org.keyboardplaying.test.TestLauncher

My question

I haven't found any spec to say if this is possible or not, and this is not a standard case, but can I specify in my MANIFEST.MF an entry point that will be found on the classpath but is not included in my JAR?


Additional Information

My MANIFEST.MF

Manifesto-version: 1.0
Archiver-version: Plexus architect
Created: from Apache Maven
Built: Chop
Build-Jdk: 1.7.0_45
Main class: org.keyboardplaying.test.TestLauncher
Class-Path: lib / slf4j-api-1.7.12. jar lib / logback-classic-1. 1.3.jar lib / logback-core-1.1.3.jar

Notes for people with problems

  • I have previously tried Class-Path: lib/*

    which I like better, but you cannot use wild cards for the classpath in manifest 1 . You can still use directories, but the classloader will not check the contents of the jars in that directory.

<sub> 1. One of the sources among others: https://stackoverflow.com/a/749862/ ...
<sub> 2. Very interesting link for entering the MANIFEST class: http://todayguesswhat.blogspot.com/2011/03/jar -manifestmf-class-path-referencing.html

+3


source to share


1 answer


Does the JAR entry point really need to be inside the JAR?

No, it is not. It is wise to put the launcher in a separate jar file, and as long as it should be fine in the classpath specified by the manifest. Here's an example:

Launching \ Launchable.java:

package launch;

public interface Launchable {
    void launch();
}

      

Launching \ Launcher.java:

package launch;

public class Launcher {
    public static void main(String[] args) throws Exception {
        System.out.println("I am the launcher!");
        Class<?> clazz = Class.forName(args[0]);
        Launchable launchable = (Launchable) clazz.newInstance();
        launchable.launch();
    }
}

      



demo \ Test.java:

package demo;

import launch.Launchable;

public class Test implements Launchable {
    public void launch() {
        System.out.println("I am Test, being launched");
    }
}

      

manifest.txt:

Manifest-Version: 1.0
Main-Class: launch.Launcher
Class-Path: launcher.jar

      

Now compile and run:

$ javac -d . launcher/*.java
$ javac -d . demo/*.java
$ jar cvf launcher.jar launcher
$ jar cvfm demo.jar manifest.txt demo
$ java -jar demo.jar demo.Test
I am the launcher!
I am Test, being launched

      

+3


source







All Articles