9
9
import java .net .MalformedURLException ;
10
10
import java .net .URI ;
11
11
import java .net .URL ;
12
+ import java .nio .file .Path ;
13
+ import java .nio .file .Paths ;
12
14
import java .util .Arrays ;
13
15
import java .util .HashSet ;
14
16
import java .util .Objects ;
24
26
import com .baeldung .classloader .internal .InternalJdkSupport ;
25
27
import com .baeldung .classloader .spi .ClasspathResolver ;
26
28
27
- class ScopedClassLoadingTest {
29
+ class ScopedClassLoadingUnitTest {
28
30
29
31
final Logger log = LoggerFactory .getLogger (getClass ());
30
32
31
33
/**
32
34
* Some ides may treat test-classes as a dynamic module-path.
33
- *
34
35
*/
35
36
private void ammendTestClasspath (Set <URL > classpath ) {
36
37
var testCp = classpath .stream ()
37
- .filter (url -> Objects .equals (url .getProtocol (), "file" ) && url .getPath ()
38
- .contains ("test-classes" ))
39
- .findFirst ()
40
- .orElse (null );
38
+ .filter (url -> Objects .equals (url .getProtocol (), "file" ) && url .getPath ()
39
+ .contains ("test-classes" ))
40
+ .findFirst ()
41
+ .orElse (null );
41
42
42
43
if (testCp == null ) {
43
44
log .info ("Amending test classpath for Eclipse" );
44
45
45
46
var loc = getClass ().getProtectionDomain ()
46
- .getCodeSource ()
47
- .getLocation ();
47
+ .getCodeSource ()
48
+ .getLocation ();
48
49
49
50
testCp = toURL (loc .toString ());
50
51
@@ -60,15 +61,15 @@ private Set<URL> createNarrowClasspath(Predicate<URL> filter) {
60
61
var loader = getClass ().getClassLoader ();
61
62
62
63
var full = ClasspathResolver .get ()
63
- .getFullClasspath (loader );
64
+ .getFullClasspath (loader );
64
65
65
66
ammendTestClasspath (full );
66
67
67
68
mergeClasspathWithModulePath (full , filter );
68
69
69
70
var classpath = full .stream ()
70
- .filter (filter )
71
- .collect (Collectors .toCollection (HashSet ::new ));
71
+ .filter (filter )
72
+ .collect (Collectors .toCollection (HashSet ::new ));
72
73
73
74
log .info ("Narrowed Classpath: \n [\n {}\n ]" , classpath );
74
75
@@ -80,14 +81,14 @@ void givenAForkedJVM_whenClassPathIsNarrowed_thenAccessWillBeLimitedToItsScope()
80
81
var scope = Pattern .compile ("(test-classes|slf|logback)" );
81
82
82
83
var classpath = createNarrowClasspath (url -> scope .matcher (url .toString ())
83
- .find ()).stream ()
84
- .map (URL ::toString )
85
- .collect (Collectors .joining (":" ));
84
+ .find ()).stream ()
85
+ .map (URL ::toString )
86
+ .collect (Collectors .joining (":" ));
86
87
87
88
var executable = ProcessHandle .current ()
88
- .info ()
89
- .command ()
90
- .orElse ("java" );
89
+ .info ()
90
+ .command ()
91
+ .orElse ("java" );
91
92
92
93
var pb = new ProcessBuilder (executable , "-cp" );
93
94
var command = pb .command ();
@@ -99,7 +100,7 @@ void givenAForkedJVM_whenClassPathIsNarrowed_thenAccessWillBeLimitedToItsScope()
99
100
pb .redirectError (Redirect .INHERIT );
100
101
101
102
log .info ("VM at PID {} will fork another JVM with narrowed classpath" , ProcessHandle .current ()
102
- .pid ());
103
+ .pid ());
103
104
104
105
var process = pb .start ();
105
106
@@ -110,7 +111,7 @@ void givenAForkedJVM_whenClassPathIsNarrowed_thenAccessWillBeLimitedToItsScope()
110
111
111
112
@ Test
112
113
void givenScopedClassLoader_whenClasspathIsNarrowed_thenAccessWillBeLimitedToItsScope () throws InterruptedException , IOException ,
113
- ReflectiveOperationException {
114
+ ReflectiveOperationException {
114
115
var thread = Thread .currentThread ();
115
116
var current = thread .getContextClassLoader ();
116
117
@@ -119,20 +120,20 @@ void givenScopedClassLoader_whenClasspathIsNarrowed_thenAccessWillBeLimitedToIts
119
120
var scope = Pattern .compile ("(test-classes|slf|logback)" );
120
121
121
122
var classpath = createNarrowClasspath (url -> scope .matcher (url .toString ())
122
- .find ()).toArray (URL []::new );
123
+ .find ()).toArray (URL []::new );
123
124
124
125
var loader = new CustomClassLoader (classpath );
125
126
126
127
thread .setContextClassLoader (loader );
127
128
128
129
try {
129
130
var service = Class .forName (ForkedService .class .getName (), true , Thread .currentThread ()
130
- .getContextClassLoader ());
131
+ .getContextClassLoader ());
131
132
132
133
assertEquals (loader , service .getClassLoader ());
133
134
134
135
((Runnable ) service .getConstructor ()
135
- .newInstance ()).run ();
136
+ .newInstance ()).run ();
136
137
} finally {
137
138
thread .setContextClassLoader (current );
138
139
}
@@ -144,22 +145,27 @@ private void mergeClasspathWithModulePath(Set<URL> files, Predicate<URL> filter)
144
145
if (modules != null && !modules .isBlank ()) {
145
146
log .info ("Converting module-path ({}) to classpath" , modules );
146
147
147
- Arrays .stream (modules .split (":" ))
148
- .map (this ::toURL )
149
- .filter (filter )
150
- .forEach (files ::add );
148
+ String pathSeparator = System .getProperty ("path.separator" );
149
+
150
+ Arrays .stream (modules .split (Pattern .quote (pathSeparator )))
151
+ .map (this ::toURL )
152
+ .filter (filter )
153
+ .forEach (files ::add );
151
154
} else {
152
155
log .info ("No module path" );
153
156
}
154
157
}
155
158
156
159
private URL toURL (String name ) {
157
- if (!name .startsWith ("file:" )) {
158
- name = "file://" + name ;
159
- }
160
160
try {
161
- return URI .create (name )
162
- .toURL ();
161
+ // If it's already a valid URL, use it as-is
162
+ if (name .startsWith ("file:" )) {
163
+ return URI .create (name ).toURL ();
164
+ }
165
+
166
+ Path path = Paths .get (name );
167
+ return path .toUri ().toURL ();
168
+
163
169
} catch (MalformedURLException e ) {
164
170
throw new UncheckedIOException (e );
165
171
}
0 commit comments