Bug 471377 - Classloader issue
Summary: Classloader issue
Status: NEW
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Golo (show other bugs)
Version: unspecified   Edit
Hardware: PC Mac OS X
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords: investigate
Depends on:
Blocks:
 
Reported: 2015-06-29 16:20 EDT by Julien Ponge CLA
Modified: 2016-05-25 10:27 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Julien Ponge CLA 2015-06-29 16:20:26 EDT
(from https://github.com/golo-lang/golo-lang/issues/271)

When I tried to override a ClassLoader with the AdapterFabric or Adapters some issues append.

(reminder) This is a part of the ClassLoader prototype:

public abstract class ClassLoader {

  //...

  public Class<?> loadClass(String name) throws ClassNotFoundException {
    //...
  }

  protected Class<?> loadClass(String name, boolean resolve) 
      throws ClassNotFoundException{
    //...
  }

  protected final Class<?> defineClass(String name, byte[] b, int off, int len)
        throws ClassFormatError {
    //...
  }

  protected final Class<?> findLoadedClass(String name) {
    //...
  }

  //...

}

Let's see what's append with the following code:

local function create = {
  return Adapter():
     extends("java.lang.ClassLoader"):
     overrides("loadClass", |super, this, name, resolve| {
        let already_loaded = this: findLoadedClass(name)
       # ...
        let defined = this: defineClass(...)        
       # ...
     }): newInstance()

}

The ClassLoader class contains two methods named loadClass. Overriding one of them cause the second one is no more visible because of the method resolution in the Adapter:

create(): loadClass("java.lang.Object")

In this case Class<?> loadClass(String name) is not resolved. This appends because the resolver find a method named loadClass in the overrided methods set and return it directly, but it's the wrong one.

The overrided methods are stored in a map with the method's name as key. So it is not possible to override two methods with the same name and with a different arity.

Another issue append when I invoke this: findLoadedClass(...) or this: defineClass(...). Both are not found in this context. It is because both methods are protected and not overrided, and according the documentation of getDeclaredMethods and getMethods there's no direct way to obtain the inherited protected method of a class.

---- Yannick Loiseau:

For the protected ones, does using super instead of this solve the problem (just a question, I have never looked at the AdapterFabric code)

---- Sylvain Desgrais:

super is a function reference not an object (it's the parent's overrided method) :wink:

---- Julien Ponge:

Overloaded methods are evil :smile:

So yes, the solution would be to have keys based not just on names, but also parameter types.

---- Yannick Loiseau:

means go for it :wink: