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.
The action api (issue 17597) is build around cookies and other classes that guide whether an action is enabled or is not. Althrough it is possible to delay the loading of action class, it is currently impossible for the implementation to delay loading of the cookie definition - because a query is done on presence of instance of that class in current action context. If we could find out that class of such name is not even loaded into VM, than the query algorithm could skip the query completelly because no class implies no instance...
A simplest hack is to make TopManager.getDefault ().systemClassLoader () implement java.util.Map and respond to queries map.get ("org.netbeans.modules.jarpackager.JarDataObject") with null or non-null values.
It would be possible for module classes. In future, it should be also possible for Core/OpenIDE classes, but not for JDK classes. It *may* be possible to do it also for JDK classes by using a bit of reflection magic, but this is probably not an option here (IMO too slow for that purpose, but on 1.4... who knows)
Also, I hope it won't interfere with classloading possibility.
What if a module is disabled and re-enabled ? I think that the function may sometimes report that the class is already loaded - and it was indeed by the "old" module's classloader. But not by the "new" one. If the query is used only to speed up the IDE, then it's probably not an issue.
1. Disabling/enabling a module is not a case for which we have to optimize for... 2. Most of the OpenIDE classes is loaded anyway (if not they should be removed from openide, but that is really futuristic right now) so I think that checking ClassLoader.getSystemClassLoader ().loadClass () and then do the enhnaced check using TopManager.systemClassLoader() will be enough. The goal is to not touch anything from module's JARs...
This would be OK ob both sides: 1. If a module is disabled, its ClassLoader will be removed from SystemClassLoader. It will be the module's classloader that will be responsible for reporting the status of a module class. 2. Anyway if it will badly report a class being loaded while not being actually loaded yet, the class will be loaded immediatelly by the real test body.
I for one think this is not worth trying to solve. I am not convinced that there is any reason to want to delay loading of the cookie (= interface). The only example given in the Enabled proposal was for a packager action to check for JarDataObject. But should not JDO just add a cookie (interface) marking it as such, and this interface can be loaded initially instead? Loading one interface class is surely not much overhead.
Jesse, I want to create an architecture where no class from unused module will be loaded. It is not enough if module can create its own cookie and declare action with dependency on it - it will not lower the number of classes loaded into VM. There has to be a solution to show action, be able to enabled it and disable and still load nothing.
Set target milestone to TBD
OK, if we're going to implement this, 4.0 is the right target given the fact we're also moving core/openide out of the classpath. On the other hand I'm thinking about a general binary cache for all the resources loaded "during the startup", which would allow loading e.g. cookie interface without even opening the module archive.
FWIW I prefer Petr's suggestion - load the interface bytecode, which is almost no overhead, and keep the architecture simpler.
Probably needs to be measured. 3kb per each (cookie) action may be acceptable. So it needs more investigation.
Is it worth the effort?
Note that if we just modified Lookup (and Lookup.Template) a bit to accept a String in place of a Class (where string == clazz.name) we would not need to refer to the interface just to see if the lookup contained it. You could write e.g. (I don't know what the actual action SPI is supposed to look like): public boolean enabled(Lookup lkp) { Lookup.Template tmpl = new Lookup.Template( "org.netbeans.api.whatever.MyCookie"); return !lkp.lookup(tmpl).allInstances().isEmpty(); } or have some declarative syntax that does the same. You would presumably still want to pass a Class when actually retrieving and using instances, since that would continue to do a runtime type check (mainly to prevent problems with module reloading): public void perform(Lookup lkp) { Lookup.Template<MyCookie> tmpl = new Lookup.Template<MyCookie>( MyCookie.class); for (MyCookie c : lkp.lookup(tmpl).allInstances()) { // .... } }
Closing this RFE as WONTFIX, as the problems covered will be better handled different way.