Skip to content

JDOM2 Migration Issues

Ryan Scheidter edited this page Oct 9, 2023 · 8 revisions

This page details the process for migrating from JDOM 1.x to JDOM2. It lays out a potential 'procedure' for doing the migration, and documents some 'gotcha' issues that you may encounter. It will only bring your code to the point where it compiles and works, but there are lots of functional enhancements that you should also apply to get the best JDOM2 experience.

JDOM2 is designed to be incompatible with JDOM 1.x (it is in org.jdom2.* instead of org.jdom.*). This means that you cannot just drop-in JDOM2. You need to make code changes. Apart from the changed package name though, the rest of JDOM2 is mostly compatible with JDOM 1.x. This means that, after changing the org.jdom2 import statements there is a very good chance that everything will 'just work'. There are small issues you may encounter that require code changes though these should be rare.

Once the code compiles with JDOM2 (after importing org.jdom2 instead of org.jdom) you can then do a number of things to tidy up your code and eliminate generics warnings.

One Potential Procedure

In your code:

  1. include the new jdom2.jar in the host classpath (keep the old jdom jar in the path for the moment).
  2. Search/replace 'import org.jdom.' with 'import org.jdom2.'
  3. Fix places where you no longer need @SuppressWarnings(...) annotations
  4. Fix places where you are using deprecated methods... there is a table of replacement mechanisms below.
  5. compile the code - check for places where you need to do other conversions, perhaps you need to import additional org.jdom2 classes...
  6. remove the jdom.jar Jar file from the classpath
  7. compile the code - check for old references that got missed somehow...
  8. Run your code
  9. ....
  10. profit ?

If you run in to any issues that are not 'import' related, then check out the 'gotcha' sections. If your issue is not addressed in the 'gotcha' sections, please drop a note on the jdom-interest mailing list.

Migration Gotcha's

There are three basic categories of issues you may encounter with a migration:

  • you extended existing JDOM Classes for example you needed to create your own special SAXBuilder or custom Element instances.
  • you just use JDOM, but a method has been deprecated.
  • you just use JDOM functionality and you have not customized JDOM itself - but you have run in to some other problem.

If you just 'use' JDOM (and have not customized it) then read up on the Deprecation, and known 'Simple' migration issues. If you have customized JDOM then you will need to read up on the SubClassing Gotchas.

Deprecation

JDOM2 has deprecated some methods. Each deprecated method has a new substitute mechanism available. There is no deprecated 'functionality', only the way to access certain functionality has changed.

The following is a list of deprecated methods, and the most likely substitution for the deprecated method.

SAXBuilder

There are now three 'Factory' concepts in SAXBuilder, so set/getFactory() has been replaced with set/getJDOMFactory()

The 'boolean' get*() methods like getExpandEntities() have been replaced with is*() methods like isExpandEntities()

There is a new XMLReaderJDOMFactory concept, which replaces the boolean 'validation' and the string-based SAXParser name concept. This has resulted in the deprecation of the get/setValidation() methods and the similar constructors, as well as the deprecation of the 'String' constructors.

For the deprecated boolean methods/constructors, use the appropriate replacement XMLReaderJDOMFactory instance, probably either XMLReaders.DTDVALIDATION or XMLReaders.NOVALIDATION

For the deprecated String constructors, use the replacement XMLReaderSAX2Factory constructors.

Simple Gotchas

Collections and Exceptions

The Content and Attribute 'List' code in JDOM2 has been revised to throw the same types of exceptions as the 'core' java.util.List classes. This makes JDOM2 more predictable for people familiar with 'standard' java.util.List implementations.

These changes have had subtle influences on 'exceptions' in JDOM2. Specifically, in the past certain types of data threw IllegalArgumentException but will now instead may throw NullPointerException (when null), or ClassCastException (if appropriate in some instances).

Other small issues that may have a subtle impact are ConcurrentModificationException, which in JDOM 1.x did not behave quite the same as the standard List implementations (but now does in JDOM2).

Thus, there is the small possiblility that you may encounter different exceptions in JDOM2 than JDOM 1.x.

AttributeType

The AttributeType enumeration is new in JDOM2. In most cases JDOM users never pay attention to the Attribute Type (ID, CDATA, NMTOKEN, etc.). In the rare case where the user does track the Attribute Type, it has been tracked using the constants in Attribute. For example, if you need to create a particular Typed Attribute in JDOM 1.x:

// JDOM 1.x example
Attribute idatt = new Attribute("id", "value", Attribute.ID_TYPE);

In JDOM 1.x the Attribute.ID_TYPE is referenced to the int value 2.

In JDOM2 the new AttributeType Enumeration contains all the same Attribute types as JDOM 1.x, but they are enumerated values, not ints. Additionally, the Attribute class has constants that references members of the AttributeType enum. Thus, in JDOM2, the exact same code as the example JDOM 1.x above will work.

// JDOM2 example same as JDOM 1.x
Attribute idatt = new Attribute("id", "value", Attribute.ID_TYPE);

// Identical JDOM2 example using direct AttributeType Enum instead of reference to enum member
Attribute idatt = new Attribute("id", "value", AttributeType.ID);

To keep as much compatibility as possible, JDOM2 has implemented the enum in the same order as JDOM 1.x which means that the 'ordinal' of each AttributeType member is the same as the JDOM 1.x constant value.

JDOM2 additionally has kept all the old methods in the API and uses an int-based conversion to convert int values to the respective AttributeType member.

The problem with the AttributeType enum is that it is not an int any more, so, any user classes that keep a reference to a type will have to have the variable type upgraded to 'AttributeType'.

This should be a very rare instance where this happens, and the fix is simple - change the variable type from 'int' to 'org.jdom2.AttributeType'.

SubClassing Gotchas

These issues are more complicated to describe, and harder to fix. If you subclass though, you should already have a good understanding of JDOM internals. So, here's just a list of the subclassing API's that have changed in JDOM2, and will impact your subclass code:

  1. SAXBuilder
  2. XPath
  3. Filter
  4. XMLOutputter
Clone this wiki locally