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.
two IllegalArgumentExceptions occured during parsing of php file. part of php editor functionality is blocked Product Version = NetBeans IDE Dev (Build 200712120000) Operating System = Windows XP version 5.1 running on x86 Java; VM; Vendor = 1.5.0_09; Java HotSpot(TM) Client VM 1.5.0_09-b03; Sun Microsystems Inc. PHP module version: built from sources 12.12.2007 steps: - start NB with fresh user dir (with flag --userdir "<path>") - create new php project - exceptions are rised on parsing created and opened php script.
Created attachment 54190 [details] php script parsing failed with the following exception.
This is problem in Languages module. There was a recent changes at 06 Dec . LanguageImpl class was added by Jan Jancura. I think as result of this and related changes all our staff is broken . I see the code in SLanguageProvider: public Language<STokenId> findLanguage (String mimeType) { if (LanguagesManager.getDefault ().isSupported (mimeType)) { try { org.netbeans.modules.languages.Language language = LanguagesManager.getDefault ().getLanguage (mimeType); if (language instanceof LanguageImpl) new Listener ((LanguageImpl) language); if (language.getParser () == null) return null; return new SLanguageHierarchy (language).language (); } catch (ParseException ex) { } catch (IllegalArgumentException ex) { // language is currently parsed } } return null; } So findLanguage method returns null if parser is null. But parser could be really null. So this is normal situation. As result we get NULL language when trying to find embedded PHP language. But this should not happens. By the way I see a number of potential problems in other patrs of code: method "public Token<STokenId> nextToken ()" in SLexer suggest that parser is not null and throw NPE when it called. SLanguageHierarchy contains method that also throws NPE if parser is null. Also please pay attention on this code in "public synchronized Language getLanguage (String mimeType) " of LanguagesManager class. RequestProcessor.getDefault ().post (new Runnable () { public void run () { try { language.read (); } catch (ParseException ex) { Utils.message ("Editors/" + mimeType2 + "/language.nbs: " + ex.getMessage ()); } catch (IOException ex) { Utils.message ("Editors/" + mimeType2 + "/language.nbs: " + ex.getMessage ()); } } }, 2000); As result "read()" method will be called in new thread. But the latter method is called from "findLanguage (String mimeType)" method ( first method that I mentioned ). And right away after this call you are trying to access to "getParser()" method . I see here a number of problems : "read()" and "getParser()" are not syncronized. But they perform read/write access to parser attribute from different thread. And Such call sequence can obviously lead to null-ness result of getParser() method call in "findLanguage" impl. Could you please fix these issues ?
Sorry for slow response, but whole NetBeans team is on vacations this week. IAE is fired because you are calling TokenHierarchy.create () method with langauge == null. You should check if PhpTokenId.getPhpLanguage () is not null in PhpModelImpl:192. SLanguageProvider.findLangauge (mimeType) returns null for given mime type, if the language is not registerred or initialized. org.netbeans.modules.languages.Langauge.getParser () returns null, if there is some langauge registerred for the mimeType, but its not initialized yet. Thats because loading and parsing of nbs file is time consuming process, and it should be done off line. SLexer.nextToken () should not throw NPE, because Lexer is not created for language that is not initialized yet. The same is true for LanguageHierarchy too. So I do not see any issue on my side.
Please see my thoughts about this : 1) In the previous version all works fine. 2) As consequence of 1) PhpTokenId.getPhpLanguage() was not null in previous version. 3) PhpTokenId.getPhpLanguage() should not be null. Because I don't know other way how to get Language. Please provide me information how I can get not-null Language ( as I already said in previous version all works fine and I didn't change anything , so I don't know the reason of current behavior ). Why is it null ? Because I need some time for waiting ? Is it true that after some time it will appears as not null ? If no : so this is issue. If yes : why clients need to implement waiting logic on their side ? I don't see any reasons to getting language in other thread and returning it as null if it was not yet initialized. Because I can't proceed further without Language reference. So I need to implement waiting logic on my side. I think in all cases any usage of getting Language need access to not-null Language and each time they will need to wait. So what is the purpose of such lazy init ?
1-3) Yes, SLanguageProvider.findLangauge ("text/php") returns null, if PHP.nbs is not loaded. And it returns not null value when PHP.nbs file is initialized. Its called lazy initialization. The purpose is performance. You should detect this state and ignore it (like return empty parse tree, or whatever - I do not know exactly your usecase). Question: "why clients need to implement waiting logic on their side ?" First, I am not sure if clients have to implement anything special in such case. In most cases you should just check null value, and skip rest of code. Just return empty parse tree, or something similar. The most of functionality should be untouched by this change. Your parser listener (or ASTEvaluator) is notified automatically when PHP.nbs file is initialized.
Well, I understood current situation. But in my case I need to implement waiting for language. So lazy initialization in my case just additional complexity. I cannot create PHP language without embedded language that is based on nbs file. But the latter language is lazy initialized after NB asking for top level language. So top level language need to wait when embedded based in nbs file language will be loaded. The option is writing language provider for top level language and lazy register it when embedded is registered but this even more complex then now.
Fixed via awaiting of initialization of embedded language.
Verified in build080131.