Apr 16, 2013

java.lang.AbstractMethodError: org.apache.xerces.dom.DeferredElementImpl.getTextContent()

org.w3c.dom.Node is an interface. org.apache.xerces.dom.DeferredElementImpl is an implementation of that interface. It seems that DeferredElementImpl does not implement getTextContent() properly. There are a lot of other implementations. If you write a program that uses DocumentBuilderFactory, then when you run it, you will actually be using one of the implementations.
You can choose between:
  • "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl"  Is the standard implementation bundled in the Sun JRE.
  • "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl" The non-standard XML parser. Specified in a library on your classpath. That is perfectly fine, but it's something you should be aware of.
The method javax.xml.parsers.DocumentBuilderFactory#newInstance() uses the following ordered lookup procedure to determine the implementation class to load:. See Javadoc for details
  1. Use the javax.xml.parsers.DocumentBuilderFactory system property.
  2. Use the properties file "lib/jaxp.properties" in the JRE directory.
  3. Use the Services API (as detailed in the JAR specification), if available, to determine the classname. The Services API will look for a classname in the file META-INF/services/javax.xml.parsers.DocumentBuilderFactory in jars available to the runtime.
  4. Platform default DocumentBuilderFactory instance.
Setting the jaxp.debug system property will cause this method to print a lot of debug messages to System.err
java -Djaxp.debug=1 YourProgram ....  or java -Djaxp.debug=true YourProgram ....
The method javax.xml.parsers.DocumentBuilderFactory#newInstance(String factoryClassName, ClassLoader classLoader) specifies the implementation class to load
How to find the JAXP implementations been used
private static void OutputJaxpImplementationInfo() {
   System.out.println(getJaxpImplementationInfo("DocumentBuilderFactory", DocumentBuilderFactory.newInstance().getClass()));
   System.out.println(getJaxpImplementationInfo("XPathFactory", XPathFactory.newInstance().getClass()));
   System.out.println(getJaxpImplementationInfo("TransformerFactory", TransformerFactory.newInstance().getClass()));
   System.out.println(getJaxpImplementationInfo("SAXParserFactory", SAXParserFactory.newInstance().getClass()));
   System.out.println(getJaxpImplementationInfo("SchemaFactory", SchemaFactory.newInstance().getClass()));
}
private static String getJaxpImplementationInfo(String componentName, Class componentClass) {
   CodeSource source = componentClass.getProtectionDomain().getCodeSource();
   return MessageFormat.format(
      "{0} implementation: {1} loaded from: {2}",
      componentName,
      componentClass.getName(),
      source == null ? "Java Runtime" : source.getLocation());
}
Possible Solutions
Update your JAXP jar implementation
  • Do a mvn dependency:tree and see if there are any xerces related jars that need to be removed or updated from an implied version  to declaring one that works
  • Google/Bing  the most recent verision of your jar library
Use the default implementation
  • Given the order used to determine the implementation to load, we can set System property javax.xml.parsers.DocumentBuilderFactory System.setProperty("javax.xml.parsers.DocumentBuilderFactory","com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
  • In command line add -Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
  • The best solution for me is passing a parameter to DocumentBuilderFactory to specify which parser to use: DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance("com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl", null);
I hope you find this information useful‎, and if you have aditional information or questions you can leave a comment :)

Jul 2, 2012

Abstract Classes, Interfaces and Why Static Abstract Methods can't be declared?

Lets make a review:
Interfaces

  • All variables defined in an interface must be public, static, and final.
  • Interface methods must not be static.
  • Interface methods implicitly are abstract and cannot have implementations.

Abstract class

  • Unlike interfaces, abstract classes can contain fields that are not static and final.
  • abstract classes can contain implemented methods.
  • An abstract class may have static fields and static methods. You can use these static members with a class reference. 
  •  Static methods in abstract classes must be implemented.

Static Methods.

  • You can call a static method with a class reference or with an object
  • Static methods can't be overriding.
  • The calls to static methods are determined by the reference type at compile time, instead of the object type which are determined in run time
  • Polymorphism aren't supported.  You can write a new static method in the subclass that has the same signature as the one in the superclass, thus hiding it.
  • It is not necessary to have any instance of the class within the static method. The compiler changes the object references  for class references when calling static methods.

Given the Java Specification, a method couldn't be Abstract and Static at the same time; You can't declare static methods in interfaces or abstract classes. Nevertheless, you can implement static methods in abstract classes.

The reason to don't allow static and abstract in the same method is that,
You can call a implemented static method, but try to figure out what should happen if you call a not-implemented static method through a class reference ( by an abstract class or interface).

You can't call a static abstract method because you haven't a specific implementation at compile time.

Also you might be thinking in implement this abstract static method in a subclass and make class references  to this method through the subclass, but it is not possible given that the static methods doesn't have polymorphic behavior

References:
Interfaces and Inheritance

Static Methods in an Interface