I'm using the spring-boot-maven-plugin to repackage a non spring application. This works fine as long as the main class is known at compile time. But I also have a jar that contains a number of importers, and it should be started using something like:

java -cp <jarfile> <mainclass>

This won't work, because the main class that needs starting is of course spring boot's launcher. So I need a way to tell the launcher at runtime what main class to start. Something like

java -DstartClass=<mainclass> -jar <jarfile>

The start class is determined in org.springframework.boot.loader.ExecutableArchiveLauncher.getMainClass, but it only takes the manifest into account. Allowing to overriding this at runtime actually is a small 3 line change:

    @Override
    protected String getMainClass() throws Exception {
        String mainClass = System.getProperty("startClass"); // maybe a more unique identifier like springBootStartClass
        if (mainClass != null) {
            return mainClass;
        }
        Manifest manifest = this.archive.getManifest();
        if (manifest != null) {
            mainClass = manifest.getMainAttributes().getValue(START_CLASS_ATTRIBUTE);
        }
        if (mainClass == null) {
            throw new IllegalStateException("No 'Start-Class' manifest entry specified in " + this);
        }
        return mainClass;
    }

The change is so small, that the fact that I cannot GIT clone the spring-boot repo (because of a "path too long" on the docker files on my windows system) seems like a very big hurdle to fix, having to install Linux and all, compared to the actual code change...

fatal: cannot create directory at 'spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/configuration/with-context/contexts/meta/ea1b2003cc8155cb8af43960c89a4c1e28777d6fd848ff3422cf375329c2626d': Filename too long

Anyone willing to make that enhancement for me?

Comment From: wilkinsona

So I need a way to tell the launcher at runtime what main class to start

This is already supported if you use PropertiesLauncher. To use this launcher, configure repackaging to produce a jar that uses ZIP layout. You can then specify the main class using loader.main.

The change is so small, that the fact that I cannot GIT clone the spring-boot repo (because of a "path too long" on the docker files on my windows system) seems like a very big hurdle to fix, having to install Linux and all.

There's no need to install Linux. The guidelines for contributing link to a separate document on working with Spring boot's code where you can find instructions for cloning the repository on Windows.

Comment From: tbee

That works very well, thank you!

If I may ask one more question; how does one include the directory of the jar in the resource resolution. It seems "-cp ." and "-Dloader.home=." do not do the trick (the log4j2.xml file is not found).

Comment From: wilkinsona

I'm not sure exactly what you've tried, but you can't use both -cp and -jar at the same time. The latter causes the former to be ignored. You probably want to use loader.path.

If you have any further questions, please follow up on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.

Comment From: tbee

Yeah, -cp was a wild try. But loader.path does the trick.

Will do. Sorry.