This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 182507 - UIDefaults.getUI() failed in OSGi on Mac
Summary: UIDefaults.getUI() failed in OSGi on Mac
Status: VERIFIED FIXED
Alias: None
Product: platform
Classification: Unclassified
Component: Module System (show other bugs)
Version: 6.x
Hardware: Macintosh Mac OS X
: P3 normal (vote)
Assignee: Stanislav Aubrecht
URL:
Keywords:
Depends on:
Blocks: 179473
  Show dependency tree
 
Reported: 2010-03-22 15:42 UTC by Tomas Danek
Modified: 2010-04-26 13:46 UTC (History)
2 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
Patch which might solve the problem (2.93 KB, patch)
2010-04-14 16:54 UTC, Jesse Glick
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Tomas Danek 2010-03-22 15:42:58 UTC
Product Version: NetBeans IDE Dev (Build 201003220200)
Java: 1.6.0_17; Java HotSpot(TM) 64-Bit Server VM 14.3-b01-101
System: Mac OS X version 10.6.2 running on x86_64; MacRoman; en_US (nb)
Userdir: /Users/tomas/.netbeans/dev
-------
- in Java IDE, create empty suite
- run this suite in Felix


run-osgi produces:

UIDefaults.getUI() failed: no ComponentUI class for: org.openide.awt.Toolbar[,0,0,0x0,invalid,layout=javax.swing.JToolBar$DefaultToolBarLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,floatable=true,margin=,orientation=HORIZONTAL,paintBorder=true]
java.lang.Error
        at javax.swing.UIDefaults.getUIError(UIDefaults.java:711)
        at javax.swing.MultiUIDefaults.getUIError(MultiUIDefaults.java:133)
        at javax.swing.UIDefaults.getUI(UIDefaults.java:741)
        at javax.swing.UIManager.getUI(UIManager.java:997)
        at javax.swing.JToolBar.updateUI(JToolBar.java:175)
        at javax.swing.JToolBar.<init>(JToolBar.java:141)
        at javax.swing.JToolBar.<init>(JToolBar.java:102)
        at javax.swing.JToolBar.<init>(JToolBar.java:90)
        at org.openide.awt.Toolbar.<init>(Toolbar.java:129)
        at org.openide.awt.ToolbarPool$Folder.acceptFolder(ToolbarPool.java:451)
Comment 1 Jesse Glick 2010-03-23 12:36:56 UTC
(There is no BZ component for core.osgi; it is unrelated to core.netigso.)

Does this only happen on Macs? If so, I cannot diagnose or fix it myself; you will need to find someone with a Mac to figure out why it is failing.
Comment 2 Tomas Danek 2010-03-23 13:16:03 UTC
will try on other platform, if it is reproducible... btw, filed as P3, since IDE seems to run ok, the only part that's affected are toolbars.
Comment 3 Tomas Danek 2010-03-23 15:00:30 UTC
seems really like mac specific. Could not reproduce on windows.
Comment 4 Jesse Glick 2010-03-23 16:50:12 UTC
OK, I will need a Mac developer to diagnose.

Note that there is likely a more useful stack trace that is getting suppressed by Swing code. (I think I filed a JRE bug for that some time ago.)
Comment 5 Antonin Nebuzelsky 2010-03-24 09:39:31 UTC
Stando, please help Jesse diagnose the problem on Mac.
Comment 6 Jesse Glick 2010-03-24 16:36:39 UTC
It is likely that UIDefaults.getUIClass is catching a discarding a CNFE which has the relevant diagnostic information (see Swing bug). Most likely the problem is that while JToolBar is in the javax.swing package which is exported from the framework bundle, and in some other L&Fs supported by Sun the base ComponentUI class is also somewhere under javax.*, for Aqua L&F the UI class is in a JRE-private namespace which the framework bundle does not export by default. As section 3.8.3 of the OSGi spec explains, this is at its root a bug in the JRE:

"Certain Java virtual machines, also SUN’s VMs, appear to make the erroneous assumption that the delegation to the parent class loader always occurs.
This implicit assumption of strictly hierarchical class loader delegation can
result in NoClassDefFoundErrors. This happens if the virtual machine
implementation expects to find its own implementation classes from any
arbitrary class loader, requiring that packages loaded from the boot class
loader not be restricted to only the java.* packages.

[...] when running on a SUN JVM, it may be necessary to specify a
value like:

   org.osgi.framework.bootdelegation=sun.*,com.sun.*

With such a property value, the Framework must delegate all java.*, sun.*,
and com.sun.* packages to the parent class loader."

Felix tries its best to strictly follow the OSGi spec and not magically permit anything which it is not required to support. (Its ClassLoader implementations do print rather helpful diagnostic messages which would have made the problem and potential solution clearer in this case, but as I said above, Swing throws this information away.)

So, assuming the L&F in question is in some com.apple.* namespace (just a guess!), you can try adding to project.properties for the suite:

  felix-sys-prop.org.osgi.framework.bootdelegation=com.apple.*

and see if that helps.

If it does, I am not sure what to recommend beyond documenting this tip; the Run in Felix action is intended to simply demonstrate what an example OSGi container would do with your app's bundles _without special configuration_. In general you would want to configure the OSGi container in various implementation-specific ways to make a production-quality app. The most common thing you need to configure is class loading, since OSGi's class loading policy is much stricter than that of the standard Java launcher, and legacy code (including some parts of the JRE) that makes unwarranted assumptions does not always work out of the box.
Comment 7 Jesse Glick 2010-03-31 21:58:41 UTC
Needs investigation on a Mac.
Comment 8 Stanislav Aubrecht 2010-04-13 08:57:21 UTC
i did some investigation and the UI class that cannot be loaded is actually org.netbeans.plaf.aqua.PlainAquaToolbarUI defined in module o.n.swing.plaf
Comment 9 Jesse Glick 2010-04-13 15:04:05 UTC
Please do not assign to me since I cannot possibly test any fix even if I could guess what it would be. I can only suggest things to investigate.

(In reply to comment #8)
> the UI class that cannot be loaded is actually
> org.netbeans.plaf.aqua.PlainAquaToolbarUI

OK, that's progress, but what is the root CNFE (what class loader is loading this class at the request of what calling code) and why is it thrown (i.e why is it not a CNFE in non-OSGi mode)?
Comment 10 Stanislav Aubrecht 2010-04-13 15:43:21 UTC
when running in Felix in debug mode the classloader is sun.misc.Launcher.AppClassLoader, the exception is ClassNotFoundException but i couldn't get any more details as the debugger doesn't have debug info for JRE classes

it's probably easily fixable by invoking
UIManager.getDefaults().put("ClassLoader", <class loader instance>);
soon enough during the startup process, see org.netbeans.swing.plaf.Startup in o.n.swing.plaf module
Comment 11 Jesse Glick 2010-04-13 16:41:45 UTC
(In reply to comment #10)
> UIManager.getDefaults().put("ClassLoader", <class loader instance>);
> see org.netbeans.swing.plaf.Startup in o.n.swing.plaf module

Well this will definitely not work in OSGi mode:

    private static final class CLValue implements UIDefaults.ActiveValue {
        public Object createValue (UIDefaults defs) {
            return Thread.currentThread().getContextClassLoader();
        }
    }

because Thread.CCL is not going to be anything special in OSGi mode (just the regular startup -classpath, i.e. felix.jar). Perhaps this should have been

            return Startup.class.getClassLoader();

? See if that helps (and breaks nothing in other run modes or L&Fs).

Better would be to use Lookup.getDefault().lookup(ClassLoader.class) but that is inaccessible from o.n.swing.plaf. Perhaps some module which can access both openide.util.lookup and o.n.swing.plaf could have an installer which calls a static method in Startup to set a good ClassLoader.
Comment 12 Stanislav Aubrecht 2010-04-14 10:59:05 UTC
well, Startup.class.getClassLoader() does fix the toolbar ui problem (because the UI classes are from the same module as the Startup class) but the UI then fails to load tab control l&f specific classes from o.n.swing.tabcontrol module
Comment 13 Jesse Glick 2010-04-14 16:54:06 UTC
Created attachment 97378 [details]
Patch which might solve the problem

Seems harmless in both regular and OSGi mode on Ubuntu. If your investigation so far is correct then this should permit all L&F classes to be loaded regardless of implementing module.
Comment 14 Stanislav Aubrecht 2010-04-15 12:51:40 UTC
the patch seems to be working fine

integrated to core-main cee3c906490e
Comment 15 Quality Engineering 2010-04-17 08:16:44 UTC
Integrated into 'main-golden', will be available in build *201004170515* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
Changeset: http://hg.netbeans.org/main/rev/cee3c906490e
User: S. Aubrecht <saubrecht@netbeans.org>
Log: #182507 -  UIDefaults.getUI() failed in OSGi on Mac
Comment 16 Tomas Danek 2010-04-26 13:46:23 UTC
verified in 20100426