99import java .net .MalformedURLException ;
1010import java .net .URI ;
1111import java .net .URL ;
12+ import java .nio .file .Path ;
13+ import java .nio .file .Paths ;
1214import java .util .Arrays ;
1315import java .util .HashSet ;
1416import java .util .Objects ;
2426import com .baeldung .classloader .internal .InternalJdkSupport ;
2527import com .baeldung .classloader .spi .ClasspathResolver ;
2628
27- class ScopedClassLoadingTest {
29+ class ScopedClassLoadingUnitTest {
2830
2931 final Logger log = LoggerFactory .getLogger (getClass ());
3032
3133 /**
3234 * Some ides may treat test-classes as a dynamic module-path.
33- *
3435 */
3536 private void ammendTestClasspath (Set <URL > classpath ) {
3637 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 );
4142
4243 if (testCp == null ) {
4344 log .info ("Amending test classpath for Eclipse" );
4445
4546 var loc = getClass ().getProtectionDomain ()
46- .getCodeSource ()
47- .getLocation ();
47+ .getCodeSource ()
48+ .getLocation ();
4849
4950 testCp = toURL (loc .toString ());
5051
@@ -60,15 +61,15 @@ private Set<URL> createNarrowClasspath(Predicate<URL> filter) {
6061 var loader = getClass ().getClassLoader ();
6162
6263 var full = ClasspathResolver .get ()
63- .getFullClasspath (loader );
64+ .getFullClasspath (loader );
6465
6566 ammendTestClasspath (full );
6667
6768 mergeClasspathWithModulePath (full , filter );
6869
6970 var classpath = full .stream ()
70- .filter (filter )
71- .collect (Collectors .toCollection (HashSet ::new ));
71+ .filter (filter )
72+ .collect (Collectors .toCollection (HashSet ::new ));
7273
7374 log .info ("Narrowed Classpath: \n [\n {}\n ]" , classpath );
7475
@@ -80,14 +81,14 @@ void givenAForkedJVM_whenClassPathIsNarrowed_thenAccessWillBeLimitedToItsScope()
8081 var scope = Pattern .compile ("(test-classes|slf|logback)" );
8182
8283 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 (":" ));
8687
8788 var executable = ProcessHandle .current ()
88- .info ()
89- .command ()
90- .orElse ("java" );
89+ .info ()
90+ .command ()
91+ .orElse ("java" );
9192
9293 var pb = new ProcessBuilder (executable , "-cp" );
9394 var command = pb .command ();
@@ -99,7 +100,7 @@ void givenAForkedJVM_whenClassPathIsNarrowed_thenAccessWillBeLimitedToItsScope()
99100 pb .redirectError (Redirect .INHERIT );
100101
101102 log .info ("VM at PID {} will fork another JVM with narrowed classpath" , ProcessHandle .current ()
102- .pid ());
103+ .pid ());
103104
104105 var process = pb .start ();
105106
@@ -110,7 +111,7 @@ void givenAForkedJVM_whenClassPathIsNarrowed_thenAccessWillBeLimitedToItsScope()
110111
111112 @ Test
112113 void givenScopedClassLoader_whenClasspathIsNarrowed_thenAccessWillBeLimitedToItsScope () throws InterruptedException , IOException ,
113- ReflectiveOperationException {
114+ ReflectiveOperationException {
114115 var thread = Thread .currentThread ();
115116 var current = thread .getContextClassLoader ();
116117
@@ -119,20 +120,20 @@ void givenScopedClassLoader_whenClasspathIsNarrowed_thenAccessWillBeLimitedToIts
119120 var scope = Pattern .compile ("(test-classes|slf|logback)" );
120121
121122 var classpath = createNarrowClasspath (url -> scope .matcher (url .toString ())
122- .find ()).toArray (URL []::new );
123+ .find ()).toArray (URL []::new );
123124
124125 var loader = new CustomClassLoader (classpath );
125126
126127 thread .setContextClassLoader (loader );
127128
128129 try {
129130 var service = Class .forName (ForkedService .class .getName (), true , Thread .currentThread ()
130- .getContextClassLoader ());
131+ .getContextClassLoader ());
131132
132133 assertEquals (loader , service .getClassLoader ());
133134
134135 ((Runnable ) service .getConstructor ()
135- .newInstance ()).run ();
136+ .newInstance ()).run ();
136137 } finally {
137138 thread .setContextClassLoader (current );
138139 }
@@ -144,22 +145,27 @@ private void mergeClasspathWithModulePath(Set<URL> files, Predicate<URL> filter)
144145 if (modules != null && !modules .isBlank ()) {
145146 log .info ("Converting module-path ({}) to classpath" , modules );
146147
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 );
151154 } else {
152155 log .info ("No module path" );
153156 }
154157 }
155158
156159 private URL toURL (String name ) {
157- if (!name .startsWith ("file:" )) {
158- name = "file://" + name ;
159- }
160160 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+
163169 } catch (MalformedURLException e ) {
164170 throw new UncheckedIOException (e );
165171 }
0 commit comments