1

How do we load additional jar at runtime along with boot jar.

Primary jar: Main.jar

Additional jar: Support.jar

Main project is a gradle boot project.

Support project is NOT a gradle project but is given compile time dependencies to the required jars.

Contents of Support project:

@RestController
@RequestMapping("/test")
public class CustomService implements WebMvcConfigurer {


    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public @ResponseBody String get() {
        return "Done!!";
    }
}

What i tried:

java -cp Support.jar:Main.jar -Dloader.path=Support.jar -Xbootclasspath/p:alpn-boot-8.1.11.v20170118.jar -Dloader.main=com.abc.app.MyApplication  org.springframework.boot.loader.PropertiesLauncher

The boot starts up fine but the endpoint is not registered.

NOTE: I had mentioned annotation scanning.

@SpringBootApplication
@ComponentScan("com.abc")
public class MyApplication {
   ....
}

Also the Main.jar will be run from various places by various users. Each user might provide his own version of Support.jar. So, hardcoding the dependency into the gradle file of Main project is not feasible.

John Eipe
  • 10,922
  • 24
  • 72
  • 114
  • As far as I recall spring boot uses custom jar format with custom class loading mechanisms. This would normally work in "plain" application, but here you can have a problem. You can TRY (never tried that) to add package of `CustomService` in `@ScanComponent` annotation as by the default, package of running application is scanned for components (and controllers) – Antoniossss Mar 21 '18 at 10:32
  • Possible duplicate of [How to add local .jar file dependency to build.gradle file?](https://stackoverflow.com/questions/20700053/how-to-add-local-jar-file-dependency-to-build-gradle-file) – anothernode Mar 21 '18 at 10:32
  • You mention "gradle boot". If you mean that your main project is Gradle based, I'd recommend going with the solution offered in the accepted answer of the question I linked to. – anothernode Mar 21 '18 at 10:36
  • @anothernode why do I need to mention this in gradle file. Isn't it possible to supply runtime dependent jars during execution time? – John Eipe Mar 21 '18 at 18:33
  • @Antoniossss I have mentioned the package scan. See edit. – John Eipe Mar 21 '18 at 18:39
  • There’s certainly more than one way to do it, but in my opinion the clean way to handle dependencies in a Gradle project is to use Gradle for it. – anothernode Mar 21 '18 at 19:14
  • So is it like if I give `runtime fileTree(dir: 'libs', include: '*.jar')` in Main project and generate jar. Then the jar can be put on another machine with a libs folder containing Support.jar and it will work? – John Eipe Mar 22 '18 at 07:01
  • No, with this approach, the JARs specified as dependencies would be included into the packaged version of your app that you generate with Gradle. The requirement that the JARs can be swapped by users of the deployed app wasn't clear to me from the original version of the question. You might still get it to work with this approach but I'm not sure. I mean, that also depends on how exactly you deploy the app then. – anothernode Mar 22 '18 at 09:15

2 Answers2

0

Try adding @ComponentScan(basePackages=full.name.of.customservice.package) to your spring application configuration, or make CustomService the same package as your @SpringApplication class

Antoniossss
  • 31,590
  • 6
  • 57
  • 99
0

try using this - org.xeustechnologies.jcl.JarClassLoader from https://github.com/kamranzafar/JCL

JCL is a configurable, dynamic and extensible custom classloader that loads java classes directly from Jar files and other sources.

Emeka
  • 51
  • 1
  • 3
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Dima Kozhevin Aug 01 '20 at 06:16