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.
200210090100, JDK1.4.1b21, MDI The module namig (core/naming) is designed as autoload module. That means, that if there is a module requiring naming enabled, it is enabled, if there is no such a module, it is disabled. Now, consider situation, when exactly one module depends on "naming". When this module is disabled, the naming is disabled too, when it is enabled, naming is enabled. The problem occurs when the naming module is to be enabled second (and more) time - the attached IllegalStateException is thrown.
Created attachment 7622 [details] IllegalStateException thrown.
The problem is the javax.naming where the initial context builder is registered is loaded by sys classloader. But when naming module is reloaded, attempt to register another instance of the builder fails. It seems to be there is no easy solution of this. "The module should be always enabled, what is not possible", so there is necessary to find out some way in the javax.naming.
Probably is necessary to make the module stable on classpath, not autotload one. Please check the patch.
Created attachment 7755 [details] changed bulid.xml (module as part of core, not autoload)
Fixed in [trunk] another way. There is set initial context factory class via system property. Then it works and naming module can remain autoload. But I think that is still not a clean solution. I suggest one in issue #28436 core/naming/../naming/Jndi.java 1.9
*** Issue 28377 has been marked as a duplicate of this issue. ***
See the commnetns in issue #28436.
Re. question in #28436: I guess it is not desirable for core/naming to get a dependency on core if this can be avoided. A static registration method forces a dependency; it could be avoided by registering the factory using lookup, though I am not sure if that will work well.
The simplest solution is to use reflection to clear the javax.naming.spi.NamingManager.object_factory_builder during uninstall. If that is not acceptable, the other solution is to register the object builder just once and let it delegate to the right installed module. I can think of: 1. core would register its own builder as soon as possible. the only functionality of the builder would be to use Lookup to find out another builder and delegate to it. If none found, processed with default implementation in javax.naming (do not know how, yet ;-) 2. the core/naming would register its builder (probably separated from the Jndi class, because it is singleton) into its META-INF/services/javax.naming.spi.**Builder* This would work correctly in the IDE, once could delete the ModuleInstall but there would have to be a way how to initialize the Builder in tests as well (running without core). I suggest to use: Lookup.getDefault (javax.naming.spi.**Builder*.class) and ensure that as soon as one loads the core/naming builder class into memory it tries to call the javax.naming.spi.NamingManager.setFactoryBuilder. So after the lookup call: new InitialContext will work.
Fixed in [trunk] the way you both described. core/src/org/netbeans/core/ProxyInitialContextFactoryBuilder.java 1.1 core/src/org/netbeans/core/NonGui.java 1.81 core/naming/manifest.mf 1.5 core/naming/src/META-INF/services/javax.naming.spi.InitialContextFactoryBuilder 1.1 core/naming/src/org/netbeans/core/naming/Jndi.java 1.11
It seems the solution isn't enough. There is a need to left the construct [snip] InitialContext ic = new InitialContext(); [snip] for other modules: Comments from Nam Nguyen: [snip] The problem for my module is that it calls into an external library which creates an InitialContext for "java.naming.corba.orb" without specifying an InitialContext factory. Since the naming module specifies the InitialContextFactoryManager, the lookup ends up using DOContext.lookup. I tried comment out the Jndi.restored() to bypass the NamingManager.setInitialContextFactoryBuilder() call. This allow the external lookup call goes correctly to URLContext.lookup(). (see jdk1.4 source InitialContext.java). Is there way for the naming module works without set the context factory builder? For example: InitialContext ic = new NbInitialContext(...); and internally NbInitialContext would set the context factory to org.netbeans.core.naming.Jndi. Thanks, -Nam [snip]
If you agree, that the current state won't work. Seems to be too invasive and probably it is necessary to left the possibility to install the default builder factory for other modules. Here are possible solutions: 1) Like above, the SFS InitialContext to be available via lookup: InitialContext ic = (IntialContext)Lookup.getDefault().lookup(InitialContext.class); 2) Let specify the factory via string when creating the SFS InitialContext: Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "org.netbeans.core.naming.Jndi"); InitialContext ic = new InitialContext(env); 3) Let the naming module expose its API: InitialContext ic = org.netbeans.core.naming.api.<somenicename>.getInitialContext(); You already said the first possibility don't like. The second one is also not nice. Currently I would prefer the last one. What do you think? Or any other solution?
4) duplicate the functionality of URLContext.lookup() We have done something like this for Context.INITIAL_CONTEXT_FACTORY, as far as I understand Nam, the corba module uses new InitialContext with some "url://scheme". We could detect that the context is URL and try to delegate to URLContext.lookup.
I don't know about URLContex.lookup(). Where is it? Also don't understand your point. How could we make such a delegating? I think it is not possible, those are different things.
I agree with Yarda so far, a default InitialContext should merge both DataObject/SFS lookup, with the default naming provided by the JDK. So that for clients it will be transparent. Maybe InitialContext.getURLOrDefaultInitCtx is what Yarda meant? I haven't studied this code much at all, but it seems that we should be able to delegate to all standard default JNDI functionality and simply add our own SFS functionality to this. Can we just set the sysprop java.naming.factory.initial rather than calling setInitialContextFactoryBuilder? See InitialContext class Javadoc.
I tried a simple fix by commenting out the setInitialContextFactoryBuilder() call in NonGUI.java and adding to boot.jar a jndiprovider.properties file with the following value: java.naming.factory.initial=org.netbeans.core.naming.JndiThis tell InitialContext.init() to use netbeans InitialContextFactory without override the URLContext usage. This works sufficiently for me so far (eventhough I still have some other ClassLoader issues to resolve somehow).
Jesse: Yarda told me what he has ment with URLContext. Yes, it is one in InitialContext. But I don't see it as a nice way how to solve this problem even how to implement it. It seem to me it would be necessary to copy the code from InitialContext into DOContext what I find kind of too tricky. It is kind of 'changing of the typical flow' from InitialContext to actual context (in our case DOContext), where it doesn't have to be. Nam: I don't understand how your example could work. Either only your intended context was working or the our one, but not both of them, I think. I guess the naming module was not enabled, thus the Proxy... has fallen back to the default (your desired) behaviour, didn't it? All: Well I somehow don't like the 4) solution, it seems to me too tricky to be the correct one. Why should be those contexts merged? What if somebody else want to provide some different context? Does he should use the another than default way? I think we shouldn't use the default and leave it for other modules wishing to have their contexts. Is it a right way from the point of view how the JNDI should work? I just don't know what is supposed to be the right solution, just got the feeling this is not the one. What do you think, isn't it worth to discuss this on nbdev first, to get some JNDI experts attention?
Jesse, in my example, the naming module is still active and its usage by looks module still work properly. It works because without specifying InitialContextFactoryManager, the corba lookup name fall correctly into url context. For other lookup, the default InitialContext has been specified by the external library jndi.properties. I think it safe in netbeans environment to default initial context to DOContext, because it is expected that JNDI applications should specify InitialContextFactory either explicitly in the environment or by default in the module Jndi.properties. The important thing for netbeans open environment is not to setInitialContextFactoryBuilder() since this block URLContext usage. BTW, I agree that this worth exposed to nbdev for attention from JDNI experts.
Nam, yes you are right, if the factory isn't specified in NamingManager directly it falls back to urlcontext first, I was blind. So your fix is working. But, now I have to make some line ------------------------------------------------------ If specified the factory via the sys prop. There is a danger (from my point of view), somebody else when registering its factory via NamingManager directly, then it disables our naming without any knowledge about it. I find it quite fragile. I'm going to ask on [nbdev] about entire issue, before start to circle additional patches and then again and again.
Hm, so I got no additional info from nbdev, so I'm hesitating what to do now. I'll wait a bit, and if no response comes, will probably fix it the way with sysprop, even I feel it isn't enough.
I think the "fragility" argument is a secondary concern. If some ill-behaved module tries to override the global JNDI context, I think we would notice pretty quickly - everything would get broken. It would not be a subtle bug, I think. Were there other outstanding questions? Someone mentioned problems with modules which provide their own jndi.properties. I don't know enough about JNDI usage to evaluate this - was the question resolved?
Using System properties is still my concern that it would override the value set by jndi.properties. I believe that setting the default initital context factory to netbeans' should be least intrusive as possible. I propose setting it in file org/netbeans/.../jndiprovider.properties in naming.jar instead of setting through System properties. But this solution would evoke another question, what will happen if some plugin need to use both netbeans context and some external library context? Will the initial context and lookup calls get resolved correctly? As Peter, my preferred solution is let explicitly set it in the env passed in each calls, and provide client of netbeans naming with some shorthand method. This way we can protect our JNDI usage and not infringe on other JNDI usages. -Nam
Correction: >I propose setting it in file >org/netbeans/.../jndiprovider.properties in naming.jar instead of >setting through System properties Please read jndi.properties in boot.jar. I tried putting it in naming.jar somehow the classloader at the usage point (project-ide) does not pick it up. Anyway, this seems to be almost the same as setting the factory in system properties, if boot.jar is always in front in the search path. So, I think that the best solution is an direct setting in the env passed to the constructor.
To the fragility: I don't think it is ill-behaved module which want to set its context as default. I wanted to say, that I think, our context shouldn't be the default one (beside that it is possible to implement only via hack, like it is currently. The hack is fragile on its own -> missing explicit dependency declaration on core, which makes the proxy factory). More important is I see it that way we are not "the most important ones" in the app runtime. We are just supporters. Therefore I think our context shouldn't be default one. I guess it is clear especially if you think about it from platform view. Therefore I'd like to reach the solution with explicit env setting (like Nam described).
Fixed in [trunk] core/src/org/netbeans/core/NonGui.java core/src/org/netbeans/core/ProxyInitialContextFactoryBuilder.java delete core/naming/src/org/netbeans/api/naming/NamingSupport.java 1.1 core/naming/manifest.mf 1.6 openidex/looks/build.xml 1.8.4.2.. openidex/looks/src/org/netbeans/api/looks/Looks.java 1.1.2.22 openidex/looks/src/org/netbeans/modules/looks/CompositeLook.java 1.4.14.12 openidex/looks/src/org/netbeans/spi/looks/DefaultLook.java 1.4.34.9 openidex/looks/src/org/netbeans/spi/looks/NamespaceSelector.java 1.1.2.10 projects/core/build.xml 1.1.2.5 projects/core/src/org/netbeans/api/projects/Project.java 1.1.2.7; projects/ide/build.xml 1.1.2.13 projects/ide/src/org/netbeans/modules/projects/ide/actions/BuildAction.java 1.1.2.3 done projects/ide/src/org/netbeans/modules/projects/ide/ui/looks/CompositeSelector.java 1.1.2.2 Note, there is not solved the issue with prohibiting setting of the context factory builder (as discussed in nbdev).
Correction it was fixed on related branches, i.e. [looks_jul_2002_private] and [prj40_prototype]
Peter please make sure that the core/naming module javadoc appears at http://www.netbeans.org/download/dev/javadoc/ I believe that you have to modify a Bundle.properties in nbbuild directory and include it...
OK I'll do that. I have to make the javadoc target in build.xml first, I guess.
I've just added the javadoc target, found also the properties file. But didn't find any info how it is processed. I'm not sure whether there are some name convetions or something else. Is somewhere the process described?
Just make sure core/naming/build.xml has a target named 'javadoc' which creates a directory core/naming/javadoc/ containing some appropriate files such as NamingAPI/ and NamingAPI.zip. Then add core/naming to ${config.fixedmodules.javadoc} in nbbuild/build.properties. See e.g. openide/execution for an example, it is not hard.
Thanks for hints, I've done it that way.
x