Wow...There definitely seems to be a lot of (continuing) problems between
Java version. I am not an expert when it comes to how the guts of the Java
ecosystem are put together so I can't comment on exactly what the best path
forward is. However, I do like the approach you took with making use of
NamespacePrefixMapper in GeoTK as it would appear to cover all the bases for
now (meaning different Java versions). I also like the skeleton
implementation idea but I don't can't comment on whether or not it would
violate any license agreements from Sun/Oracle.  Seems like you have a way
ahead with that though.

So, +1 from me on your approach to adding the skeleton class in sis-utility
and modifying the maven build accordingly. Does anyone know when Java 8 is
supposed to be released? 

Adam

-----Original Message-----
From: Martin Desruisseaux [mailto:[email protected]] 
Sent: Sunday, February 24, 2013 11:53 AM
To: Apache SIS
Subject: Blocking issue on XML prefix mapping

Hello all

I'm back on work more immediately related to ISO 19115 and I'm still facing
a blocking issue. A solution exists, but is not very satisfying.

The ISO/OGC standards are huge, and use a large amount of different XML
schemas with different prefixes. The new revision of ISO 10115 (to be
published this year) adds yet more prefixes in the mix. Some of those
prefixes are hard-coded in Apache SIS [1], but this list is still
incomplete.

XML uses prefixes in order to differentiate tags of different schemas, a
little bit like Java uses package names to differentiate classes of
different libraries. Problem is: those prefixes are auto-generated by JAXB
at marshalling time, and those auto-generated names are not very informative
("ns1", "ns2", "ns3", etc.). JAXB provides a @XmlSchema annotation allowing
us to specify explicitly the prefixes, but it doesn't seem to work well with
JAXB 2.1.

With JAXB 2.1, there is apparently no other way to control the prefixes than
subclassing com.sun.xml.internal.bind.NamespacePrefixMapper. 
Problem is: this class is obviously internal, so we are not supposed to use
it. However in this particular case, Sun/Oracle seems to have made an
exception to their own rules since NamespacePrefixMapper is publicly advised
as the way to control prefixes ([2], [3]).

I have read reports on internet saying that the @XmlSchema annotation has
been fixed in JAXB 2.2.4. However while JDK 1.7.0_15 is bundled with JAXB
2.2.4-2 (so it would theoretically work), JDK 1.6.0_37 is still bundled with
JAXB 2.1.10 so @XmlSchema would not work on that platform. 
Furthermore I have not yet verified if @XmlSchema on JDK7 really works for
us, and even the JAXB 2.2.6 documentation still advise NamespacePrefixMapper
as the way to control prefix names [3].

So I'm tempted to continue to use NamespacePrefixMapper for now (this is
what was done on Geotk), until we verified that the standard annotations
work. We may have to commit the NamespacePrefixMapper hack anyway since (in
my understanding) @XmlSchema will never work on Oracle JDK6. At some later
time, we could remove the hack on the JDK7 branch while keeping it on the
JDK6 branch.

However while com.sun.xml.internal.bind.NamespacePrefixMapper exists in
every Oracle JDK6/7 distributions, it is not accessible by the javac
compiler. Some possible workaround are:

  * Use the non-standard -XDignore.symbol.file javac option, which will
    disable the exclusion of "com.sun" packages. However this is an
    Oracle-specific option.
  * Explicitly put rt.jar on the classpath as a Maven dependency using
    <scope>system</scope>. But this is again Oracle-specific, and is ugly.
  * Provide a skeleton of
    com.sun.xml.internal.bind.NamespacePrefixMapper in the sis-utility
    module with only the signature of the methods that we need to
    override (hopefully it would not be a licensing violation if we do
    not provide any code), and exclude that class file from the JAR file.


The last workaround seems the only JDK-independent solution to me. 
However if we choose this approach, we still have to find how to exclude the
com/** classes from the JAR file. The maven-jar-plugin has an <exclude>
configuration option for that [4], but despite all my attempts I have been
unable to make it work - I tried in the root pom.xml, in the module pom.xml,
inside and outside <execution> block, with different goals, with different
paths (relative, absolute), Maven seems to just ignores any configuration
and unconditionally include the com.sun files. 
Surely I'm doing something wrong, but I didn't found what. I also tried the
maven-clean-plugin execution under the "process-classes" phase, without more
luck (plugin is executed, but my include/exclude configuration is ignored).
This leave us with one more goal we could define in our custom
sis-build-helper plugin...

So in summary, one way to go forward would be:

  * Use NamespacePrefixMapper despite being in a package that we are not
    supposed to use.
  * Commit a skeleton of NamespacePrefixMapper in sis-utility module, so
    we can compile.
  * Add a goal in sis-build-helper for deleting the above class before
    building the JAR file.
  * After we verified that the tests pass, try to replace
    NamespacePrefixMapper by the standard @XmlSchema annotation on the
    JDK7 branch (but we would probably have to keep
    NamespacePrefixMapper on the JDK6 branch). It is possible that
    @XmlSchema still doesn't work well enough on JDK7 and that we have
    to wait for JDK8 before removing NamespacePrefixMapper.


Is there any comment, or an other approach that we could try? For the
record, JIRA task is at [5].

     Martin


[1]
https://svn.apache.org/repos/asf/sis/trunk/sis-utility/src/main/java/org/apa
che/sis/xml/Namespaces.java
[2] http://java.sun.com/webservices/docs/1.5/jaxb/vendorProperties.html
[3]
http://jaxb.java.net/nonav/2.2.6/docs/ch03.html#marshalling-changing-prefixe
s
[4] http://maven.apache.org/plugins/maven-jar-plugin/usage.html
[5] https://issues.apache.org/jira/browse/SIS-74


Reply via email to