Title: Jython has problems to dynamically loading classes when installed on the boot classpath
Type: Severity: normal
Components: Documentation Versions:
Status: open Resolution: remind
Dependencies: Superseder:
Assigned To: Nosy List: fwierzbicki, leosoto, nriley, pjenvey, zyasoft
Priority: low Keywords:

Created on 2008-09-13.18:47:45 by leosoto, last changed 2013-02-27.17:37:32 by fwierzbicki.

msg3522 (view) Author: Leonardo Soto (leosoto) Date: 2008-09-13.18:47:45
As discussed on
<>, configuring
jython on the bootclasspath (as the current launcher script does) is
causing problems when dynamically loading classes which "live" on the
normal CLASSPATH (i.e, when using Class.forName()).

This typically impacts the use of JDBC drivers.
msg3523 (view) Author: Leonardo Soto (leosoto) Date: 2008-09-13.18:48:32
#1096 is clearly related to this issue.
msg3524 (view) Author: Leonardo Soto (leosoto) Date: 2008-09-13.18:49:04
Oh, and for the record, the current workaround is to use the --verify
flag when starting jython.
msg3543 (view) Author: Leonardo Soto (leosoto) Date: 2008-09-13.22:27:14
#1129 is also this problem
msg3580 (view) Author: Nicholas Riley (nriley) Date: 2008-09-14.04:05:26

>>> Class.forName('')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(
	at java.lang.reflect.Method.invoke(

The full stack looks like:

Class<T>.forName(String) line: 169	
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39	
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25	
Method.invoke(Object, Object...) line: 597	
PyReflectedFunction.__call__(PyObject, PyObject[], String[]) line: 162	
PyReflectedFunction.__call__(PyObject[], String[]) line: 170	
PyReflectedFunction(PyObject).__call__(PyObject) line: 273	
_pyx2.f$0(PyFrame) line: not available	
_pyx2.call_function(int, PyFrame) line: not available, PyObject) line: 187	
PyTableCode(PyCode).call(PyFrame) line: 14	
Py.runCode(PyCode, PyObject, PyObject) line: 1200	
Py.exec(PyObject, PyObject, PyObject) line: 1227	
InteractiveConsole(PythonInterpreter).exec(PyObject) line: 134	
InteractiveConsole(InteractiveInterpreter).runcode(PyObject) line: 90	
InteractiveConsole(InteractiveInterpreter).runsource(String, String, String) line: 71	
InteractiveConsole(InteractiveInterpreter).runsource(String, String) line: 46	
InteractiveConsole.push(String) line: 110	
InteractiveConsole.interact(String, PyObject) line: 90[]) line: 294	
jython.main(String[]) line: 114	

So the problem is that Class.forName uses ClassLoader.getCallerClassLoader, whereas we want it to use another 

>>> Thread.currentThread().getContextClassLoader()
>>> Class.forName('', True, Thread.currentThread().getContextClassLoader())
<jclass 1>

At least for cases like #1129 and #1096, we could change Jython's and zxJDBC's Class.forName calls to 
explicitly specify a classloader, as above.

Another issue is people using Class.forName explicitly from Jython.  In general it looks like we need to have 
the invoking class have a "valid" classloader.  From instrumenting ClassLoader.getCallerClassLoader, that 
ends up being PyReflectedFunction.  So, maybe we can load PyReflectedFunction from somewhere else to get 
around this?
msg4229 (view) Author: Jim Baker (zyasoft) Date: 2009-03-12.07:28:43
Deferred to 2.5.1 (or later)
msg5050 (view) Author: Leonardo Soto (leosoto) Date: 2009-08-17.15:19:36
I think that the machinery needed to workaround the problem and support
using Class.forName from Python code is not worth the effort. 

I propose to explicitely discourage Class.forName(''), since
you can get the desired effect either by doing  "import", if
the class name is known beforehand, or __import__(className), if it's not.

We could even hack PyReflectedFunction to check if it is going to call
Class.forName(String) and print a loud warning.
msg5243 (view) Author: Philip Jenvey (pjenvey) Date: 2009-10-20.04:54:07
+1 on discouraging Class.forName, this was my original suggestion before 
we decided to remove it. However if we can hack PyReflectedFunction to 
warn on its call, how much harder would it be really to hack it to call 
another class loader instead?
Date User Action Args
2013-02-27 17:37:32fwierzbickisetresolution: remind
components: + Documentation, - Core
2009-10-20 04:54:08pjenveysetmessages: + msg5243
2009-08-17 15:19:36leosotosetmessages: + msg5050
2009-03-12 07:28:43zyasoftsetpriority: low
nosy: + zyasoft
messages: + msg4229
2008-12-14 17:14:47fwierzbickisetnosy: + fwierzbicki
2008-12-10 08:36:28pjenveysetnosy: + pjenvey
2008-09-14 04:05:27nrileysetnosy: + nriley
messages: + msg3580
2008-09-13 22:27:14leosotosetmessages: + msg3543
2008-09-13 18:49:04leosotosetmessages: + msg3524
2008-09-13 18:48:32leosotosetmessages: + msg3523
2008-09-13 18:47:46leosotocreate