« Do you drive on freeways? | Main | Search is getting better »

September 24, 2009

Fix error "getTextContent is undefined for the type Node" for Solr project in Eclipse IDE

The error:

"The method getTextContent() is undefined for the type Node"
You get 3 of these, in the source files ReutersService.java and TestConfig.java

A Web fix that doesn't work:

You'll see suggestions that org.w3c.dom.Node.getTextContent() is only available as of Java 1.5.  But when you check you see you ARE running with Java 1.5 or later.

You can quickly check this by right clicking on the project, Properties -> Java Compiler, and confirm that 1.5 or above are in the drop down lists.

The fix, short story:

The order of the classpath needs to be tweaked in Eclipse project; shove the xml-apis-1.0.b2.jar all the way to the bottom, past the built in JVM libraries.

For more details, and how you would know this, read on!

Spotting this problem in Eclipse:

Go back toe the Eclipse "Problems" tab where you saw the 3 errors.  If you don't see that tab, go to Window -> Show View -> Problems.

Any of the errors will get us there, but I think the 3rd one is the easiest, the one in TestConfig.java line 65 (as of this writing, it may shift over time)

This line and the line before it should look like this:

    Node node = solrConfig.getNode("propTest", true);
    assertEquals("prefix-proptwo-suffix", node.getTextContent());

Mouse over the capitalized word "Node" on the previous line, the yellow balloon assist should show "org.w3c.dom.Node".

Now highlight the word Node.

Right click, select Declarations -> Workspace.

In a moment a new "Search" tab should appear and report 2 declarations for org.w3c.dom.Node, in:

/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/classes.jar

and

xml-apis-1.0.b2.jar

It's the second entry that's causing the problem, it's being pulled in from the contrib/extraction area, which Eclipse included but ant doesn't.

You'd think that since it's listed second and Eclipse highlights the first result, that maybe it's the first "framework" library that's being found and gumming up the words, but in this case the order presented in the results is misleading.

The root cause:

There are many jars packaged with Solr and they sometimes contain the same library routines, but at different versions.  When Eclipse imported the Solr project it tries to create a reasonable default classpath to build with, but the order matters, and in this case the list and order is different than what the ant build utility would have created.

Although Eclipse is very popular, it is not the "official" build tool for the Apache Software Foundation projects, for many (all?) the tool is ant, and they do their testing against ant.  So when you import ASF projects into Eclipse, you sometimes have to do a bit of tweaking.

Comparing Eclipse and Ant Class Paths:

To see the respective build paths (ant and Eclipse) I'd recommend using two different directories.  Or, when you're running ant, make sure you've exited Eclipse.  And whenever you startup Eclipse, make sure to do a "refresh" on the top level project folder, so that Eclipse see's the changes command line ant has made.

For ant, cd into the project directory, for example:

cd solr-nightly

If you've previously run a build, do an "ant clean".

Then use the command:

ant -d > ../solr-ant.out 2>&1

For Eclipse, you actually don't need to be running the IDE.  Instead, cd into that same project directory and look at the .classpath file.  Remember, since it has a dot as the first character, you'll need to do ls -a on Unix to see it, or just type in the filename directly.

You might want to make a copy of this file, putting that copy next to the ant output, to compare the difference.

Note that most of the entries have kind="lib", that's not what I mean by the "lib" jar files.  I'm talking about the entries near the bottom that also have path="lib/...

Fixing in the Eclipse IDE:

Right click project, select Properties -> Java Build Path.

Though we will eventually need to use the "Order and Export" tab, it's a very long list, and there's actually a shortcut to finding the xml-apis-1.0.b2.jar file we want to move.  Go to the Libraries tab which lists things alphabetically.  Scroll down the the x's and single click that entry.  Don't click the checkmark, just the name.

Now switch back to the Order and Export tab scroll down, you'll notice that library is still highlighted, pretty cool!

Click the Bottom button on the right, to move it all the way down.  It should show up AFTER the special "JRE System Library [JVM ...." entry.  And it should not have a checkmark.

Save the settings with the OK button and Eclipse should recompile everything, it might take it a second to wake up.  But the Problems tab should now have no Errors, although still a ton of warnings.  But those are a matter for another day!

Fixing in at the Command Line:

This is not supported but if you insist:

Make sure Eclipse is NOT running.

Make a backup copy of your .classpath file.

Find the xml-apis entry, the exact line number will vary.

Move it to the near the end of the file, on the line AFTER the kind="con" entry.  The end of your file should now look like:

...
    <classpathentry kind="lib" path="lib/wstx-asl-3.2.7.jar"/>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
    <classpathentry kind="lib" path="contrib/extraction/lib/xml-apis-1.0.b2.jar"/>
    <classpathentry kind="output" path="build"/>
</classpath>

Restart Eclipse and verify you can build without error.

Final thoughts on Eclipse and these Ant Projects:

This issue of the class path being radically different between an ant build and an imported Eclipse build could have many other side effects.  For example, if you import Lucene into Eclipse, you'll get tons of errors due to the different configuration.

And this problem is compounded by the fact that, because Lucene and Solr use rather sophisticated ant files, the normal Eclipse trick of importing from an ant file won't work - Eclipse doesn't understand the fancier ant files.

Reading the web the target build environment is ant, not Eclipse, so this is not likely to change.  Also it sounds like many of the committers are using IntelliJ instead of Eclipse, so may not notice this.  The point being you'll generally not be able to effortlessly import the Lucene related projects into Eclipse.  I don't think the newer version of Eclipse fixes this ant import issue, so get used to tweaking Eclipse projects.

If you create your Eclipse project by having it fetch the Subversion repository (the SVN option in the project wizard), you are allow to save the project and then go back and tweak the build settings.  At point you can sort of wire up the ant files, it Eclipse does see the default target (look for the blue entry near the bottom of the list), but the Java error markers are not fully integrated, so it makes it less than idea.

In a pinch, use the command line tools.

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d8341c84cf53ef0120a5edb02f970c

Listed below are links to weblogs that reference Fix error "getTextContent is undefined for the type Node" for Solr project in Eclipse IDE:

Comments

Thank you soooooo much! This is exactly the problem I had. Thanks for the detailed explanation, it helps a lot. Congrats for the text!
I admire people like you who exchange so precious information to help other java developers.

Best regards from Brazil!

Muchas gracias, me ha sido muy Ăștil.

=)

Thx v much.The spotting this problem section helped a great deal.As in my case Element was getting sourced from 3 jars.So even after moving xml-apis it wasn;t working.Spotted the 3rd jar and moved it below xml-apis i.e both xml-apis and jtidy were at the end after the JRE stuff.All errors resolved now.

My problem started when I upgraded the JRE. It placed the new JRE library at the bottom of my build path. So I simply moved it back to where it was originally. Thank you very much for the insight into how the Eclipse build path works.

I also wanted to thank you for your reply. It worked perfectly in my situation also. I am a very experienced software developer but a total newbie in Eclipse and Java working on a very complex java solution and it truly is nice to see an answer which deals with the issue in a straightforward and helpful manner.

Verify your Comment

Previewing your Comment

This is only a preview. Your comment has not yet been posted.

Working...
Your comment could not be posted. Error type:
Your comment has been saved. Comments are moderated and will not appear until approved by the author. Post another comment

The letters and numbers you entered did not match the image. Please try again.

As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

Having trouble reading this image? View an alternate.

Working...

Post a comment

Comments are moderated, and will not appear until the author has approved them.