Community
Participate
Working Groups
ASTParser in 3.0 can be used in another standalone program to create Eclipse ASTs without actually running Eclipse. As the documentation says: char[] source = ...; ASTParser parser = ASTParser.newParser(AST.JLS2); // handles JLS2 (J2SE 1.4) parser.setSource(source); CompilationUnit result = (CompilationUnit) parser.createAST(null); But this doesn't work in 3.1 because ASTParser always gets the plugin object, and when it is null (in the case of a standalone program), a null pointer exception is raised. Please look at JavaCore.getOptions(). In 3.0, it tests if the result of getPlugin() is null; in 3.1, the test disappears, hence causing the problem.
You need at least a headless Eclipse. The JDT/Core plugin needs to be initialized.
Looking at the doc I don't find a reference saying that DOM/AST should work in a stand-alone application.
I'm just thinking, if the parser CAN work without being called in a plugin, why it SHOULDN'T? A simple test is easy to add to it, and the fix makes it backward compatible with 3.0.
With the new bridging method between the java element and the dom nodes, the java model needs to be initialized. This means that the JDT/Core plugin needs to be initialized.
So is this not going to be fixed? We like to write tests for our parsing code outside of the environment. We use JUnit and FitNesse. Both sets of tests fail when we upgrade to 3.1. Is there a workaround we can use to get our tests running again?
(In reply to comment #4) > With the new bridging method between the java element and the dom nodes, the > java model needs to be initialized. This means that the JDT/Core plugin needs to > be initialized. What about making all bridging method return null when JDT/Core is not initialized?
Close as WONTFIX. DOM API are designed to work within a headless Eclipse.
You need to define your code within a plugin and run your JUnit tests as JUnit plugin tests. Your plugin would have org.eclipse.jdt.core as a requirement.
Olivier I understand this is a hard pb. I really think this should re-considered though. Coudl you at least tempora There is a wealth of treasure available in the JDT core code whic is ready to be re-used outside of Eclipse. That would be really sad if none could benefit from it. In the last week i have talkedd to at least three person that asked about it.
Could you talk with the team about it?
I think having ASTParser working outside of eclipse and without the need for all the dependencies to run a headless eclipse is important. The JDT compiler is starting to be used outside of eclipse, Tomcat, and we are looking to use it with Drools, http://drools.org, so it's only natural that projects like these would like to have access to a powerful tool like ASTParser. I fully understand that at this time its not practical, but I think this should be marked as a future item, not as a WONT FIX.
Sorry but my comments was cut mid-way. I was asking if you could at least re-open that bug?
Reopening. Olivier if the change is small, then we may be able to do it. If not, keep it for Later.
(In reply to comment #13) > Reopening. Olivier if the change is small, then we may be able to do it. If > not, > keep it for Later. > I just added two lines of code to use JDT as a stand alone Java parser. This might be a quick and dirty fix, but you folks can make it better. Sung <hunkim@gmail.com> Index: JavaCore.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java,v retrieving revision 1.517 diff -u -r1.517 JavaCore.java --- JavaCore.java 14 Dec 2005 14:59:11 -0000 1.517 +++ JavaCore.java 27 Dec 2005 20:06:49 -0000 @@ -2569,6 +2569,9 @@ * @see JavaCorePreferenceInitializer for changing default settings */ public static Hashtable getOptions() { + if (getPlugin() == null) { + return new Hashtable(); + } return JavaModelManager.getJavaModelManager().getOptions(); }
We need to do two things to fix this PR properly. 1) Access to the options when JDT/Core is not initialized. 2) Provide a name environment in order to be able to get bindings. The bridge methods would not work (since the Java model doesn't exist), but we must expose the bindings. Right now this assumes that a java project is available. If JDT/Core is not initialized, there is no java project. If someone has an API to propose to fix the second point, please speak up.
*** Bug 93948 has been marked as a duplicate of this bug. ***
For M6 we can target a solution that would allow the creation of the AST, but no binding would be available.
Fixed and released in HEAD. Martin, Could you please try the next integration build? I could use the ASTParser without running the platform.
Olivier, thanks!
(In reply to comment #18) > Fixed and released in HEAD. > Martin, > > Could you please try the next integration build? I could use the ASTParser > without running the platform. > Yes, it works for me well. Thanks for the quick solution, it helps us very much!
Can anyone summarize what will and will not be available due to the lack of bindings when running outside of Eclipse? I'm somewhat of a newbie on the AST Parser, so I'm not sure what function is included in the bindings.
Bindings contains the resolved information. For example if you have a method header like this: String foo() { ... } Then the IMethodBinding for the method foo will tell you that the return type is java.lang.String. Without the bindings, it is impossible to know that String comes from the java.lang package. You could have defined your own class String. The reason why no bindings are available when used outside of Eclipse is that there is no context to resolve the bindings. Within Eclipse, the java project provides the context. In order to resolve bindings, we would need to provide a new API that could allow the user to give the context in which the bindings will be resolved. But this is beyond the scope of this bug report.
Verified for 3.2 M6 using build I20060328-0010
*** Bug 97444 has been marked as a duplicate of this bug. ***
I m trying to create and parse AST using the following code. I use eclipse IDE to do so. I have tried both eclipse 3.1 and 3.2. When I went through the forum I found few others are also facing the same problem, and reply posted to them was that they may be running it outside eclipse. In my case I am running it in the eclipse environment. Pls help..... Errors that I got: Exception in thread "main" java.lang.ExceptionInInitializerError at org.eclipse.jdt.core.JavaCore.getOptions(JavaCore.java:2401) at org.eclipse.jdt.core.dom.ASTParser.initializeDefaults(ASTParser.java:222) at org.eclipse.jdt.core.dom.ASTParser.<init>(ASTParser.java:204) at org.eclipse.jdt.core.dom.ASTParser.newParser(ASTParser.java:109) at provaCompilatore.parse(provaCompilatore.java:21) at provaCompilatore.main(provaCompilatore.java:46) Caused by: java.lang.NullPointerException at org.eclipse.jdt.internal.core.search.indexing.IndexManager.getJavaPluginWorkingLocation(IndexManager.java:284) at org.eclipse.jdt.internal.core.search.indexing.IndexManager.<init>(IndexManager.java:50) at org.eclipse.jdt.internal.core.JavaModelManager.<init>(JavaModelManager.java:671) at org.eclipse.jdt.internal.core.JavaModelManager.<clinit>(JavaModelManager.java:649) ... 6 more -------------------------------------- Here my code: ------------------------------ import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.CompilationUnit; public class provaCompilatore { provaCompilatore(){ } public void parse(){ ASTParser parser = ASTParser.newParser(AST.JLS3); } public static void main(String[] args) { provaCompilatore prova = new provaCompilatore(); prova.parse(); } } ---------------------------- here the jars I added: org.eclipse.core.resources_3.1.0.jar org.eclipse.core.runtime_3.1.1.jar org.eclipse.jdt.core_3.1.1.jar
Is there another bug open for the issue with setResolveBindings not working in the standalone version of the ASTParser?
From looking at the code, I think the way to solve this problem would be something like: In CompilationUnitResolver, create an overloaded resolve() method with the new signature: public static void resolve( ICompilationUnit[] compilationUnits, String[] bindingKeys, ASTRequestor requestor, int apiLevel, Map options, CancelableNameEnvironment env, int flags, IProgressMonitor monitor) Note: The IJavaProject and WorkingCopyOwner parameters have been replaced with a CancelableNameEnvironment parameter. This is fine, since the existing resolve() already creates a CancelableNameEnvironment parameter from those two arguments - so this is an easy change. Then, add code to create a CancelableNameEnvironment that does not depend on a JavaProject or WorkingCopyOwner. This is the hardest change. It may be necessary to abstract the CancelableNameEnvironment behind an interface. Finally, change the internalCreateAST() method in ASTParser to generate the CancelableNameEnvironment in the above way, if the project and/or owner wasn't specified. This is an easy change also. So the bulk of the work, it seems to me, would be adding functionality to create a CancelableNameEnvironment (or something equivalent that would share the same interface) without a project or working copy owner.
Actually... We don't need a new way to create the environment. Users of the class can create their own instance of INameEnvironment. The ASTParser could take it as a parameter and would use it when calling the new overloaded resolve() method. There's already a class that implements INameEnvironment without needing a Project or anything: org.eclipse.jdt.internal.compiler.batch.FileSystem.java So users of the ASTParser would just create an instance of FileSystem with the right parameters, and pass it as an INameEnvironment to the ASTParser. This would allow the ASTParser to pass the environment to the CompilationUnitResolver, without needing a project or a working copy.
Created attachment 78520 [details] Patch allows use of ASTParser to generate bindings outside of Eclipse environment
The above patch implements what I'm talking about. By allowing the user of an ASTParser to specify the INameEnvironment to use (which does not have to be coming from an eclipse project... see FileSystem class that implements INameEnvironment), setResolveBindings can now work without needing to be part of an active Eclipse environment.
I have opened a new bug for the binding resolution issue: https://bugs.eclipse.org/bugs/show_bug.cgi?id=87852
Oops, the correct new bug URL is: https://bugs.eclipse.org/bugs/show_bug.cgi?id=206391
I am running Eclipse 3.3.0 build I20070625-1500 and it would appear that this fix did not make it into that code base as I continue to receive the java.lang.NoClassDefFoundError: org/eclipse/core/runtime/Plugin error. Would this fix not have been merged into the 3.3 branch?
You still need to provide a bunch of jars on the classpath, but the JavaCore doesn't need to be initialized.
Thanks for the comment Oliver, that got me on the right track. The jar's required appear to be as follows: org.eclipse.core.contenttype_3.*version*.jar org.eclipse.core.jobs_3.*version*.jar org.eclipse.core.resources_3.*version*.jar org.eclipse.core.runtime_3.*version*.jar org.eclipse.equinox.common_3.*version*.jar org.eclipse.equinox.preferences_3.*version*.jar org.eclipse.jdt.core_3.*version*.jar org.eclipse.osgi.services_3.*version*.jar org.eclipse.osgi_3.*version*.jar org.eclipse.text_3.*version*.jar