atom feed17 messages in org.jdom.jdom-interestRe: [jdom-interest] Java 5 planning
FromSent OnAttachments
Jason HunterMar 4, 2008 1:38 pm 
Victor ToniMar 4, 2008 2:54 pm 
RolfMar 4, 2008 5:58 pm 
Mattias JiderhamnMar 4, 2008 11:38 pm 
Mattias JiderhamnMar 4, 2008 11:49 pm 
Michael KayMar 5, 2008 1:35 am 
Joe BowbeerMar 5, 2008 5:05 am 
Victor ToniMar 5, 2008 5:24 am 
Michael KayMar 5, 2008 7:15 am 
Mattias JiderhamnMar 6, 2008 12:03 am 
Jason HunterMar 8, 2008 12:43 am 
Michael KayMar 8, 2008 1:57 am 
Jason HunterMar 8, 2008 2:48 am 
Michael KayMar 8, 2008 9:49 am 
Timothy MarcMar 8, 2008 12:25 pm 
Mattias JiderhamnMar 12, 2008 2:02 am 
Tatu SalorantaMar 12, 2008 9:41 am 
Subject:Re: [jdom-interest] Java 5 planning
From:Rolf (jd@tuis.net)
Date:Mar 4, 2008 5:58:31 pm
List:org.jdom.jdom-interest

Hi Jason, All.

Jason Hunter wrote:

First off, I want to thank Rolf for investing his time in exploring the technical feasibility of a JDOM migration to a Java 5 baseline. A few other people have explored the area in the past as well, and it feels like (especially with JDOM 1.1 now finished) we can look at this in earnest. You're welcome. What I'd like to do here is take a high level view and ask some questions of our local Java 5 porting experts -- Rolf, Mattias, Victor, Gregor, and any others with experience porting widely-adopted projects to Java 5.

1. I think we can all agree the ideal scenario is to develop a drop-in replacement, a new JAR which (so long as you're on Java 5+) would let previously compiled code continue to work. This would let us continue development as usual with a new release (call it 1.2 or 1.5 or 2.0) simply having a higher Java version requirement. How far can we go down the road of embracing Java 5 while still maintaining this?

2. A less ideal scenario would require any previously compiled code to be recompiled against the new JAR, but wouldn't require any code changes. This will cause some confusion and effort but to an acceptably small amount. Rolf, you say your build requires a recompile and in 99% of cases doesn't require code changes. Where are the gaps? Can they be filled?

3. The fallback scenario is one where people will need to modify existing code in order to use the new version. This will cause some pain, and should we follow this path I think we should look at what steps we can take to mitigate it. Automated upgrade scripts? A new package, like org.jdom5, so people can choose to use the old version or the new? Other possibilities?

4. Lastly, I'd like to hear from people on what specific advantages they're looking for in an upgrade to a Java 5 baseline.

My answers:

I'll start with (4) because you need to know why before you know how. I think people would most like to improve the return values of methods to be more specific. For example, getChild() should return Element, getChildren() should return List<Element>, text.getParent() should return Element, doctype.getParent() should return Document, and so on. Are there other "big ticket" items?

On (1) I suspect that without a source recompile we can't adjust the method return types which is the core value of the upgrade.

On (2) from Rolf's README it looks like there are two areas likely to require code changes based on his port: the Filter.filter() change and the AttributeType enum. Both seem like things to do if you're already requiring code changes but aren't things so valuable in and of themselves that we should require people do a code change. Are there more?

-jh-

My answers, also starting with 4:

4a. For me the biggest advantage of a Java5 baseline is to reduce "compiler warnings". I rely on strict rules in the Eclipse development environment that do everything from ensuring that all method parameters are documented in the JavaDoc tags, ensure that methods that are overridden have the @Override annotation, etc. This leads to code which is well structured, and complete. My 'lint checking' in eclipse is more pedantic than the warnings generated from just the javac compiler. By porting JDom to Java5 I can *correctly* eliminate many warnings in my code, and this improves the signal-to-noise ratio in the code problems. I feel that it is important to be able to compile code without compiler warnings. Other people have different programming styles, but for me, a good Java5 port of JDom will make my life 'cleaner'.

4b. The next advantage is to be able to use the generic return types of methods to 'simplify' the code readability. Let's face it, "for (Element kid : root.getChildren()) {...}" is just so simple.

1. While I agree that a pure drop-in replacement jar would be ideal, I think too much would be compromised to get there. Looking at my prototype port, I imagine it could potentially be done, but then the AttributeType ENUM would have to be reverted. This is not actually a "big deal" I guess, using String constants is not bad, and I only used Enum because it is 'cool'. I think there may be other issues though... the change I made to 'Filter' class would require a recompile because I changed a method signature from accepting Object to accepting Content.... this would not work with a drop-in replacement. So, I think it *may* be possible, but unlikely. There may be more effort spent building a compromised product to accomplish a lofty goal which, for me, seems unnecessary.

2. This is the approach I aimed for... make the migration simple, and a recompile will do. There are some issues in the prototype that may/will cause issues: - I changed a couple of method signatures have parameters that were more closely typed than JDom 1.1, like the Filter class above, where I take a Content parameter instead of an Object. In JDom1.1 it would not have made sense to send in non-Content data anyway, but it would have complied. With the prototype, it will not compile. As a result of this same change, it is now no longer possible to build a filter which returns Document... but, is there anyone out there who has a use case for that? JDom 1.1 had reference in the JavaDoc for the Filter class that you could build a filter that matches Document objects, but I could not think of a use case, and I 'needed' to have a Content input type, not Object, so I decided to drop support for it. This may cause compile problems for a small fraction of people. - Some people may have specific references to Attribute Types that in JDom1.1 are String values... think along the lines of someone having the following in their code: String attype = Attribute.ID_TYPE. This will no longer compile because in the prototype, Attribute types are of the Enumerated AttributeType, and the code would have to become: AttributeType attype = Attribute.ID_TYPE. I don't believe AttributeTypes are used by many people, and the impact would be low. - people who have chosen to have their own implementations of the Filter interface will be pretty messed up with the port. Then again, this is a 'major release', and a change of interface is OK, right? Similarly, people who have extended any of the classes in JDom will have issues with compile errors... One issue already encountered is that some people have already modified their 'legacy' code to be 'generified'. Mattias, for example, has done the following to his applications:

List<Element> something = (List<Element>)XPath.newInstance("/some/xpath").selectNodes();

the above will compile with a compiler warning on this line, but, all the subsequent references to the 'something' list will have the benefits of generics. Unfortunately, this means that the 'new' version of JDom will, unless it exactly returns List<Element>, will cause compile errors.... for example, it is possible that a final version of the selectNodes() method will return List<? extends Content>, and even this will cause compile *errors* in Mattias's code.

So, a bigger problem with the 'recompile and it works' situation is perhaps not the true legacy code, but the code which is ported to Java5 already but will have different generics.... For what it's worth, in my legacy code ports I just happen to have used the wild-card generics to access Jdom, like List<?> kids = root.getChildren(), and, as a consequence, I have no problems.... perhaps other people will be OK too.

When I said 99% of people should get away with recompiles only, I was not aware of the situations like Mattias's. I need to revise that number much lower now...

3. Substantially changing the method signatures is something that I tried to avoid in the prototype, but, based on subsequent discussions, it appears that there may be places where this would be advantageous. XPath has generated some interesting challenges, and one solution would be requiring a second parameter to XPath constructors which would be the class of the return type... like: List<Element> something = XPath.newInstance("/some/path", Element.class).selectNodes(); I have actually built this alternate mechanism in an unpublished version of my prototype, and it does work quite well, and also conforms to the standard practices...

Additional Issues...

Based on discussions earlier, it appears that XPath may be a real problem with Generics. The 'right thing' for XPath to do depends on Jaxen, and, since that is not 'generified' we are stuck. The reason Jaxen is not generified is pretty obvious, because it is a whole lot more complicated to impose generics on a method call like Xpath.newInstance("//@*")....

Victor has made suggestions for the Filter class which are likely to be less intrusive than the changes I made in the prototype, but no-one has actually explored his suggestions yet.

Conclusion...

I don't believe that we can get a good Java5 API without at least compile-time compatibility. I think to get the best API we will probably need to resort to having substantially changed API's.

I think there are going to be compile-time errors for some people regardless of which route we decide to take....