Could you provide a standalone runnable script to reproduce the issue?
BTW, the script is expected to be written in Groovy/Java.

Cheers,
Daniel Sun
On 2020/08/08 13:19:01, Saravanan Palanichamy <chava...@gmail.com> wrote: 
> Hello
> 
> I have an extension of GroovyClassLoader that I use as follows
> 
> a) I override loadClass to make sure I decide where to load from
> b) I first call loadClass on my parent class loader to make sure the class is 
> not loaded there (I assert if it is. This code is not shown below)
> c) I then call loadClass after turning off all script loading on 
> myclassloader to make sure this class is not already loaded. If it is, I just 
> use that
> d) If I get a class not found exception, I know this class is not already 
> loaded and so I look up a local repository to fetch a string based script and 
> call parseClass (I do all of this in the context of loadClass)
> 
> This used to work with 2.5.x but when I upgrade to 3.0.5, it sits in a 
> blocked state (not sure if it is blocked on some mutex because of a recursion 
> some where). When I use my debugger , when it gets to this state, I am not 
> able to read any of my variable values in the debugger (which seems to 
> indicate some threading read lock somewhere)
> 
> Question :- Am I doing this the right way? Why does it block and not load the 
> class? It locks up in the parseClass invocation (inside a validate call that 
> validates the sourceCode object
> 
> My code looks like this
> 
> class MyClassLoader constructor(
>     private val repository: FlowsRepository,
>     private val configuration: CompilerConfiguration,
>     parentClassLoader: ClassLoader
> ) : GroovyClassLoader(parentClassLoader, configuration) {
> 
>     /** Load class [name] either from repository or class path */
>     override fun loadClass(
>         name: String,
>         lookupScriptFiles: Boolean,
>         preferClassOverScript: Boolean,
>         resolve: Boolean
>     ): Class<*> {
>         return try {
>             // Never try to load from script files, always parse from 
> repository
>             super.loadClass(name, false, true, resolve)
>         } catch (e: ClassNotFoundException) {
>             // Try fetching it from the repository
>             parseFromRepository(name)
>         }
>     }
> 
>     /** Parse [name] from the flow repository and cache it */
>     private fun parseFromRepository(name: String): Class<*> {
> 
>         // Fetch flow source
>         val flow = repository.fetchFlow(name) ?: throw 
> ClassNotFoundException("Unable to find flow $name")
> 
>         // Parse the class if found
>         try {
>             // If parseClass yields a class whose name does not match 
> (typically when we are trying to find an inner
>             // class (A.B) by parsing the outer class source file (A.groovy), 
> throw class not found. The compiler will
>             // attempt to then find A$B which is how inner classes are stored 
> in the class loader. This find will
>             // succeed (this process is repeated for inner classes inside 
> inner classes)
>             super.parseClass(flow.sourceCode, true)
> 
>             // The class parsed may not be the class you are looking for, but 
> it may be an inner class, so
>             // use the cache to get it
>             return getClassCacheEntry(name) ?: throw 
> ClassNotFoundException("Unable to find flow $name")
>         } catch (e: CompilationFailedException) {
>             throw CodeQualityException("Compile error", e)
>         }
>     }
> }
> 

Reply via email to