Skip to content

Commit d5b1a5f

Browse files
committed
jooby-run: allow to use a single class loader #3098
- Use a single/fat class loader to run your application. This is required on complex project classpath where you start seeing weird reflection errors. This was the default mode in Jooby 2.x. The new model since 3.x uses a modular classloader which improves restart times and memory usage making it faster. Default is: `false`. - fix #3098
1 parent c186aee commit d5b1a5f

5 files changed

Lines changed: 39 additions & 2 deletions

File tree

docs/asciidoc/dev-tools.adoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ The next example shows all the available options with their default values:
110110
<compileExtensions>java,kt</compileExtensions> <3>
111111
<port>8080</port> <4>
112112
<waitTimeBeforeRestart>500</waitTimeBeforeRestart> <5>
113+
<useSingleClassLoader>false</useSingleClassLoader> <6>
113114
</configuration>
114115
</plugin>
115116
...
@@ -139,6 +140,7 @@ joobyRun {
139140
compileExtensions = ["java", "kt"] <3>
140141
port = 8080 <4>
141142
waitTimeBeforeRestart = 500 <5>
143+
useSingleClassLoader = false <6>
142144
}
143145
----
144146

@@ -147,6 +149,7 @@ joobyRun {
147149
<3> Source extensions. A change on these files trigger a compilation request, followed by a restart request.
148150
<4> Application port
149151
<5> How long to wait after last file change to restart. Default is: `500` milliseconds.
152+
<5> Use a single/fat class loader to run your application. This is required on complex project classpath where you start seeing weird reflection errors. This was the default mode in Jooby 2.x. The new model since 3.x uses a modular classloader which improves restart times and memory usage making it faster. Default is: `false`.
150153

151154
For Maven and Gradle there are two variant `mvn jooby:testRun` and `./gradlew joobyTestRun` they work
152155
by expanding the classpath to uses the `test` scope or source set.

modules/jooby-gradle-plugin/src/main/java/io/jooby/gradle/RunTask.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ public class RunTask extends BaseTask {
6262
*/
6363
private Long waitTimeBeforeRestart;
6464

65+
private Boolean useSingleClassLoader;
66+
6567
/**
6668
* Run task.
6769
*
@@ -85,6 +87,7 @@ public void run() throws Throwable {
8587
.orElseGet(() -> computeMainClassName(projects));
8688

8789
JoobyRunOptions config = new JoobyRunOptions();
90+
config.setUseSingleClassLoader(useSingleClassLoader = Boolean.TRUE);
8891
config.setMainClass(mainClass);
8992
config.setPort(port);
9093
if (compileExtensions != null) {
@@ -235,6 +238,16 @@ public void setRestartExtensions(List<String> restartExtensions) {
235238
this.restartExtensions = restartExtensions;
236239
}
237240

241+
@Input
242+
@org.gradle.api.tasks.Optional
243+
public Boolean isUseSingleClassLoader() {
244+
return useSingleClassLoader;
245+
}
246+
247+
public void setUseSingleClassLoader(Boolean useSingleClassLoader) {
248+
this.useSingleClassLoader = useSingleClassLoader;
249+
}
250+
238251
/**
239252
* List of file extensions that trigger a compilation request. Compilation is done via Maven or
240253
* Gradle. Default is: <code>java</code> and <code>kt</code>.

modules/jooby-maven-plugin/src/main/java/io/jooby/maven/RunMojo.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ public class RunMojo extends BaseMojo {
7373

7474
private boolean useTestScope;
7575

76+
@Parameter(property = "jooby.useSingleClassLoader")
77+
private boolean useSingleClassLoader;
78+
7679
@Override
7780
protected void doExecute(List<MavenProject> projects, String mainClass) throws Throwable {
7881
Maven maven = getMaven();
@@ -143,6 +146,7 @@ private JoobyRunOptions createOptions(String mainClass) {
143146
if (restartExtensions != null) {
144147
options.setRestartExtensions(restartExtensions);
145148
}
149+
options.setUseSingleClassLoader(useSingleClassLoader);
146150
return options;
147151
}
148152

@@ -184,6 +188,14 @@ public void setRestartExtensions(List<String> restartExtensions) {
184188
this.restartExtensions = restartExtensions;
185189
}
186190

191+
public boolean isUseSingleClassLoader() {
192+
return useSingleClassLoader;
193+
}
194+
195+
public void setUseSingleClassLoader(boolean useSingleClassLoader) {
196+
this.useSingleClassLoader = useSingleClassLoader;
197+
}
198+
187199
protected void setUseTestScope(boolean useTestScope) {
188200
this.useTestScope = useTestScope;
189201
}

modules/jooby-run/src/main/java/io/jooby/run/JoobyRun.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,9 +374,8 @@ public void start() throws Throwable {
374374
.map(Path::toString)
375375
.collect(Collectors.joining(File.pathSeparator));
376376
System.setProperty("jooby.run.classpath", classPathString);
377-
var classloaderType = System.getProperty("jooby.run.classloader", "");
378377
JoobyModuleFinder finder;
379-
if ("single".equals(classloaderType)) {
378+
if (options.isUseSingleClassLoader()) {
380379
finder =
381380
new JoobySingleModuleLoader(
382381
options.getProjectName(), classes, resources, dependencies, watchDirs.keySet());

modules/jooby-run/src/main/java/io/jooby/run/JoobyRunOptions.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ public class JoobyRunOptions {
3030

3131
private Long waitTimeBeforeRestart = DEFAULT_WAIT_TIME_BEFORE_RESTART;
3232

33+
private boolean useSingleClassLoader;
34+
3335
private static final long DEFAULT_WAIT_TIME_BEFORE_RESTART = 500L;
3436

3537
static final long INITIAL_DELAY_BEFORE_FIRST_RESTART = 5000L;
@@ -88,6 +90,14 @@ public void setPort(Integer port) {
8890
this.port = port;
8991
}
9092

93+
public boolean isUseSingleClassLoader() {
94+
return useSingleClassLoader;
95+
}
96+
97+
public void setUseSingleClassLoader(boolean useSingleClassLoader) {
98+
this.useSingleClassLoader = useSingleClassLoader;
99+
}
100+
91101
/**
92102
* How long to wait after last file change to restart. Default is: <code>500</code> milliseconds.
93103
*

0 commit comments

Comments
 (0)