@@ -5,62 +5,61 @@ import scala.language.unsafeNulls
5
5
6
6
import java .lang .ClassLoader
7
7
import java .lang .invoke .{MethodHandles , MethodType }
8
- import java .lang .reflect .Modifier
9
- import java .net .{ URL , URLClassLoader }
10
- import java .lang .reflect .{ InvocationTargetException , UndeclaredThrowableException }
8
+ import java .lang .reflect .{Modifier , InvocationTargetException , UndeclaredThrowableException }
9
+ import java .net .{URL , URLClassLoader }
11
10
12
11
import scala .annotation .internal .sharable
13
12
import scala .annotation .tailrec
14
13
import scala .util .control .Exception .catching
15
14
16
- final class RichClassLoader (private val self : ClassLoader ) extends AnyVal {
17
- /** Execute an action with this classloader as context classloader. */
18
- private def asContext [T ](action : => T ): T = ScalaClassLoader .asContext(self)(action)
15
+ object ClassLoaderOps :
16
+ private def setContext (cl : ClassLoader ) = Thread .currentThread.setContextClassLoader(cl)
19
17
20
- /** Load and link a class with this classloader */
21
- def tryToLoadClass [T <: AnyRef ](path : String ): Option [Class [T ]] = tryClass(path, initialize = false )
22
-
23
- /** Load, link and initialize a class with this classloader */
24
- def tryToInitializeClass [T <: AnyRef ](path : String ): Option [Class [T ]] = tryClass(path, initialize = true )
18
+ extension (self : ClassLoader )
19
+ /** Execute an action with this classloader as context classloader. */
20
+ def asContext [T ](action : => T ): T =
21
+ val saved = Thread .currentThread.getContextClassLoader
22
+ try
23
+ setContext(self)
24
+ action
25
+ finally setContext(saved)
25
26
26
- private def tryClass [T <: AnyRef ](path : String , initialize : Boolean ): Option [Class [T ]] =
27
- catching(classOf [ClassNotFoundException ], classOf [SecurityException ]) opt
28
- Class .forName(path, initialize, self).asInstanceOf [Class [T ]]
27
+ /** Load and link a class with this classloader */
28
+ def tryToLoadClass [T <: AnyRef ](path : String ): Option [Class [T ]] = tryClass(path, initialize = false )
29
29
30
- /** Run the main method of a class to be loaded by this classloader */
31
- def run (objectName : String , arguments : Seq [String ]): Unit = {
32
- val clsToRun = tryToInitializeClass(objectName).getOrElse(throw new ClassNotFoundException (objectName))
33
- val method = clsToRun.getMethod(" main" , classOf [Array [String ]])
34
- if ! Modifier .isStatic(method.getModifiers) then
35
- throw new NoSuchMethodException (s " $objectName.main is not static " )
36
- try asContext(method.invoke(null , Array (arguments.toArray: AnyRef ): _* ))
37
- catch unwrapHandler({ case ex => throw ex })
38
- }
30
+ /** Load, link and initialize a class with this classloader */
31
+ def tryToInitializeClass [T <: AnyRef ](path : String ): Option [Class [T ]] = tryClass(path, initialize = true )
39
32
40
- @ tailrec private def unwrapThrowable (x : Throwable ): Throwable = x match {
41
- case _ : InvocationTargetException | // thrown by reflectively invoked method or constructor
42
- _ : ExceptionInInitializerError | // thrown when running a static initializer (e.g. a scala module constructor)
43
- _ : UndeclaredThrowableException | // invocation on a proxy instance if its invocation handler's `invoke` throws an exception
44
- _ : ClassNotFoundException | // no definition for a class instantiated by name
45
- _ : NoClassDefFoundError // the definition existed when the executing class was compiled, but can no longer be found
46
- if x.getCause != null =>
47
- unwrapThrowable(x.getCause)
48
- case _ => x
49
- }
33
+ private def tryClass [T <: AnyRef ](path : String , initialize : Boolean ): Option [Class [T ]] =
34
+ catching(classOf [ClassNotFoundException ], classOf [SecurityException ]) opt
35
+ Class .forName(path, initialize, self).asInstanceOf [Class [T ]]
50
36
51
- // Transforms an exception handler into one which will only receive the unwrapped
52
- // exceptions (for the values of wrap covered in unwrapThrowable.)
53
- private def unwrapHandler [T ](pf : PartialFunction [Throwable , T ]): PartialFunction [Throwable , T ] =
54
- pf.compose({ case ex => unwrapThrowable(ex) })
55
- }
37
+ /** Run the main method of a class to be loaded by this classloader */
38
+ def runMain (objectName : String , arguments : Seq [String ]): Unit =
39
+ val clsToRun = tryToInitializeClass(objectName).getOrElse(throw ClassNotFoundException (objectName))
40
+ val method = clsToRun.getMethod(" main" , classOf [Array [String ]])
41
+ if ! Modifier .isStatic(method.getModifiers) then
42
+ throw NoSuchMethodException (s " $objectName.main is not static " )
43
+ try asContext(method.invoke(null , Array (arguments.toArray: AnyRef )* ))
44
+ catch unwrapHandler({ case ex => throw ex })
56
45
57
- object RichClassLoader {
58
- implicit def wrapClassLoader (loader : ClassLoader ): RichClassLoader = new RichClassLoader (loader)
59
- }
46
+ @ tailrec private def unwrapThrowable (x : Throwable ): Throwable = x match
47
+ case _ : InvocationTargetException | // thrown by reflectively invoked method or constructor
48
+ _ : ExceptionInInitializerError | // thrown when running a static initializer (e.g. a scala module constructor)
49
+ _ : UndeclaredThrowableException | // invocation on a proxy instance if its invocation handler's `invoke` throws an exception
50
+ _ : ClassNotFoundException | // no definition for a class instantiated by name
51
+ _ : NoClassDefFoundError // the definition existed when the executing class was compiled, but can no longer be found
52
+ if x.getCause != null =>
53
+ unwrapThrowable(x.getCause)
54
+ case _ => x
60
55
61
- object ScalaClassLoader {
62
- def setContext (cl : ClassLoader ) = Thread .currentThread.setContextClassLoader(cl)
56
+ // Transforms an exception handler into one which will only receive the unwrapped
57
+ // exceptions (for the values of wrap covered in unwrapThrowable.)
58
+ private def unwrapHandler [T ](pf : PartialFunction [Throwable , T ]): PartialFunction [Throwable , T ] =
59
+ pf.compose({ case ex => unwrapThrowable(ex) })
60
+ end ClassLoaderOps
63
61
62
+ object ScalaClassLoader :
64
63
def fromURLsParallelCapable (urls : Seq [URL ], parent : ClassLoader | Null = null ): URLClassLoader =
65
64
new URLClassLoader (urls.toArray, if parent == null then bootClassLoader else parent)
66
65
@@ -70,13 +69,4 @@ object ScalaClassLoader {
70
69
MethodHandles .lookup().findStatic(classOf [ClassLoader ], " getPlatformClassLoader" , MethodType .methodType(classOf [ClassLoader ])).invoke().asInstanceOf [ClassLoader ]
71
70
catch case _ : Throwable => null
72
71
else null
73
-
74
- extension (classLoader : ClassLoader )
75
- /** Execute an action with this classloader as context classloader. */
76
- def asContext [T ](action : => T ): T =
77
- val saved = Thread .currentThread.getContextClassLoader
78
- try
79
- setContext(classLoader)
80
- action
81
- finally setContext(saved)
82
- }
72
+ end ScalaClassLoader
0 commit comments