JDK-4120021 : UIDefaults.getUI() always uses the system class loader.
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.0,1.1
  • Priority: P1
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 1998-03-16
  • Updated: 1999-01-15
  • Resolved: 1999-01-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.2.0 1.2beta4Fixed
Related Reports
Relates :  
Relates :  
Description
 > Eduardo Pelegri-Llopart writes:
 >  > As far as I can see, the existing code for UIDefaults.getUIClass()
 >  > assumes that the classloader where UIDefaults is runnig is the same
 >  > where the UIClass is [e.g. it does a plain Class.forName()].
 >  > 
 >  > I'm running a BeanBox, on which I am loading javahelp.jar.  When I
 >  > try to instantiate a JHelpViewer component, UIDefaults cannot find
 >  > my componentUI.
 >  > 
 >  > At first sight, it would seem that UIManager.getUI(target) should
 >  > find what is the classloader for target's class and try to locate
 >  > the UI relative to it.  But maybe you have something else in mind.

Hans Muller writes: 
 > You're right and that is a significant bug.  Unfortunately I don't think
 > just using the class loader of the target will work because that assumes
 > that the component, e.g. JSlider, will be loaded by the same class
 > loader as the look and feel.  That would work for JavaHelp but not
 > for someone who was providing a new L&F for the built-in Swing classes.
 > I think this needs more thought.  If you have any ideas let me know.

On the longer-term issue, I think that one "natural" way to do it is
to build on the default ComponentUI table.  THat table is supposed to
map between a Componennt UID and the name of a class. Maybe it should map
to the name of a class + a classloader instace.  Or to a "lazy value"
for a class object [I know Swing has the notion of a lazy value but I
don't know if it is powerful enough to use it this way].

Once a mechanism like that exists, a provider for a JComponent can use
the existing propertyChange event on "lookAndFeel" to register the proper
class to use.

	- eduardo

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.2beta4 FIXED IN: 1.2beta4 INTEGRATED IN: 1.2beta4
14-06-2004

EVALUATION This is a bug, the description contains my evaluation. hans.muller@Eng 1998-05-20 I was mistaken about the way class loaders worked. They're organized as a tree and LeafClassLoader.loadClass() trys the loaders on the path from the root (the system class loader) to the LeafClassLoader. So in the example I was concerned about both the JSlider and its UI would be loaded by the system class loader, which is fine. I've added an override of UIDefaults.getUI() that takes a class loader argument: public Class getUIClass(String uiClassID, ClassLoader uiClassLoader) { try { String className = (String)get(uiClassID); Class cls = (Class)get(className); if (cls == null) { if (uiClassLoader == null) { cls = Class.forName(className); } else { cls = uiClassLoader.loadClass(className); // NEW } if (cls != null) { // Save lookup for future use, as forName is slow. put(className, cls); } } return cls; } catch (ClassNotFoundException e) { return null; } catch (ClassCastException e) { return null; } }
11-06-2004

WORK AROUND Not really. I had to patch the run-time swing class files to make this work.
11-06-2004

PUBLIC COMMENTS UIDefaults.getUI() always uses the system class loader.
10-06-2004