29

I've been using com.sun.xml.bind.marshaller.NamespacePrefixMapper in my project, and i had no problem with it in JDK 6u17. Now I just updated to 6u18, and I saw that it has been replaced to com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper. However if I import this class and try to compile my classes, I get the error:

package com.sun.xml.internal.bind.marshaller does not exist
import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper;

I can access this package through the NetBeans code completion feature, and NetBeans does not highlight the code for errors.

Any help would be appreciated!

Leonel
  • 28,541
  • 26
  • 76
  • 103
Daniel Szalay
  • 4,041
  • 12
  • 57
  • 103

9 Answers9

21

I don't think that the class com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper is a replacement of com.sun.xml.bind.marshaller.NamespacePrefixMapper, the former is there for a long time and it NOT MEANT TO BE USED BY YOU AT ALL (hence the internal packaging).

The problem here is that JavaSE 6 doesn't have the JAXB RI (it has a JAXB implemenation but not JAXB RI) so if you want to rely on RI specific feature, you should bundle JAXB RI in your application (and that would protect you from JAXB changes in Java SE).

Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
  • that sounds logical, but then - why are these packages there? – Bozho Feb 24 '10 at 14:09
  • @Bozho As I wrote, Java 6 includes a JAXB implementation which is **not** JAXB RI so if you want to rely on a JAXB RI specific feature you should bundle it. So yes, the blog post is incorrect as the author was explicitly using a RI specific feature (which is why he faced problems with JavaSE changes, like the OP). – Pascal Thivent Feb 24 '10 at 14:22
  • @Bozho It is indeed. But that `internal` packaging should make you run and look for another solution. Using `internal` is at best a temporary solution, you just don't know when it will break. – Pascal Thivent Feb 24 '10 at 14:23
  • yes, but on the other hand you are already using something internal - it's in `com.sun`, and I doubt many people will instinctively look for the subtle difference – Bozho Feb 24 '10 at 14:29
  • @Bozho `com.sun` stuff is already "tricky" (you're supposed to know what you're doing) so `com.sun.*.internal` is logically worse :) Anyway, in this particular case, discussing about this `internal` stuff is just a consequence of a wrong initial assumption (the mentioned class is not a replacement). Just ignore internal stuff and there is no issue. – Pascal Thivent Feb 24 '10 at 14:37
  • Thanks for all the answers! I used `NamespacePrefixMapper` to "disable" prefixes, but since it is not very essential right now for me. So I will let the default prefix mapper work (or a more costful way; use string operations to replace prefixes). – Daniel Szalay Feb 24 '10 at 14:45
  • @wheelie That's perfectly fine and you can continue to use it (but you need to bundle the jars of JAXB RI with your app). – Pascal Thivent Feb 24 '10 at 14:52
  • 6
    Bundling my app with a fixed version of JAXB RI worked fine. It is required as the version bundled with java changes. A few versions are shown [here](https://jaxb.java.net/guide/Which_JAXB_RI_is_included_in_which_JDK_.html). But this list is far from complete. In maven I added the following build dependency: ` com.sun.xml.bind jaxb-impl 2.2.4-1 `. This enables you to use `com.sun.xml.bind.marshaller.NamespacePrefixMapper` (without "internal") on whatever java version you are using. – Coder Nr 23 Jan 21 '14 at 10:32
18

The NamespacePrefixMapper is not usable anymore.

Use the annotations in package-info.java:

@javax.xml.bind.annotation.XmlSchema(namespace = "http://nameSpaceUri"
, xmlns = {
    @XmlNs(prefix = "myPrefix", namespaceURI = "http://nameSpaceUri")
}
, elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)

package my.package.;

This works with the JAXB bundled with JDK7, for other JDK version update JAXB to 2.2.4.

Daniel Szalay
  • 4,041
  • 12
  • 57
  • 103
Daniel De León
  • 13,196
  • 5
  • 87
  • 72
  • 1
    What happens if you're using a WSDL-first approach? Won't your `package-info.java` get overridden by wsimport each time you clean your project? – Catchwa Oct 22 '12 at 00:42
  • When I have to face that, I just copy the autogenerated code to the source folder of another project. – Daniel De León Oct 24 '12 at 18:08
5

You are not supposed to use com.sun.** classes directly. They are deemed to be internal and subject to change without notice. (And look what just happened!!) The fact that the new class has internal in the package name is an even bigger hint!

I strongly suggest that you look for a better way of doing what you are doing ... that doesn't use the com.sun.** classes.

EDIT - hmmm, looks like whoever is responsible for the JAXB RI has broken the Sun rules about package names for that extension! And it is also unfortunate that Sun has not implemented this particular RI extension in JDK 6.0.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 1
    in this case this is an API problem actually, because this feature is "advertised" as a way of determining namespace prefixes, and it is also a custom provider property. see http://java.sun.com/webservices/docs/1.5/jaxb/vendorProperties.html and http://fisheye5.atlassian.com/browse/~raw,r=1.600/jaxb-architecture-document/www/doc/com/sun/xml/bind/marshaller/NamespacePrefixMapper.html – Bozho Feb 24 '10 at 13:17
  • 1
    (my point being - there is no better way to do this, and this is an essential feature) – Bozho Feb 24 '10 at 13:22
4

Sun had made something not quite appropriate in this case. The namespace mapper isn't included in the spec, but it is "advertised" as a way to customize prefixes. So the general advice "don't use com.sun.*" doesn't apply here, and the javadoc of this class says:

Implemented by the user application to determine URI -> prefix mapping.

Check this article and see if it would work for you.

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • I do not agree with the suggested solution. Here, the OP explicitly needs to bundle the JAXB RI jars with his application (as I explain in my answer), `internal` stuff is meant to scare you away. – Pascal Thivent Feb 24 '10 at 14:03
  • Also, if you look at the source code to Sun's NamespacePrefixMapper.java, the author has written: "be careful about changing this class. this class is supposed to be extended by users and therefore we are not allowed to break those user code." So yes, Sun is really confusing people by putting a class that is "supposed to be extended by users" into an internal package. – vocaro Dec 25 '10 at 07:46
  • 3
    The "Check this article" link is dead. – koppor Jun 08 '13 at 09:21
3

For those using maven, found including both JAXB-RI and JAXB for java6 via this link worked.

http://mvnrepository.com/artifact/com.googlecode.jaxb-namespaceprefixmapper-interfaces/JAXBNamespacePrefixMapper/2.2.4

Steve
  • 39
  • 1
1

I ran into this recently when porting some older code into a new project. The old project compiled just fine using ant, however the new one failed with the error you mention above.

After some digging, I found that the old build.xml file uses a javac compiler option to bypass the restriction above:

<javac srcdir="${srcDir}" destdir="${outputDir}" classpathref="classpath" debug="on">
    <compilerarg value="-XDignore.symbol.file" />
</javac>

After finding it, I searched and found this other stackoverflow question: Using internal sun classes with javac

Community
  • 1
  • 1
Travis
  • 2,654
  • 4
  • 26
  • 46
1

The below post at stack overflow answers the question: Define Spring JAXB namespaces without using NamespacePrefixMapper

Key is to include the rt.jar at build time and remove it from the application after compilation.

Community
  • 1
  • 1
Mr. Doomsbuster
  • 1,324
  • 13
  • 11
1

Adding this dependency to maven fixed it for me:

<dependency>
    <groupId>com.googlecode.jaxb-namespaceprefixmapper-interfaces</groupId>
    <artifactId>JAXBNamespacePrefixMapper</artifactId>
    <version>2.2.4</version>
</dependency>
ANU279
  • 21
  • 2
0

For me, using JBoss, the fix required explicitly adding a line to WEB-INF/jboss-deployment-structure.xml

JBoss AS7 has a class loading mechanism which is different from previous versions.

Add the line '', in the structure like so:

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.1">

<deployment>
<dependencies>

<module name="com.sun.xml.bind" />

</dependencies>
</deployment>
</jboss-deployment-structure>
Adam Wise
  • 2,043
  • 20
  • 17