我有一些代码使用JAXB API类,它们是作为Java 6/7/8中JDK的一部分提供的.当我使用Java 9运行相同的代码时,在运行时我得到错误,指示无法找到JAXB类.
自Java 6以来,JAXB类已作为JDK的一部分提供,为什么Java 9不再能够找到这些类?
Java 9 弃用了六个包含Java EE API的模块,它们将很快被删除:
javax.activation包的java.activationjavax.activity,javax.rmi,javax.rmi.CORBA,和org.omg.*包javax.transaction包的java.transactionjavax.xml.bind.*包的java.xml.bindjavax.jws,javax.jws.soap,javax.xml.soap,和所有javax.xml.ws.*包javax.annotation包的java.xml.ws.annotation哪些维护的第三方工件提供了这些API?它们提供这些API或它们必须提供的其他功能并不重要 - 重要的是,它们是这些模块/包的直接替代品吗?
为了更容易收集知识,我回答了迄今为止我所知道的并将答案作为社区维基.我希望人们能够扩展它,而不是写出自己的答案.
在您投票结束之前:
显然,com.sun.xml.bind:jaxb-impl 工件在 Maven 存储库中被标记为“旧JAXB 运行时模块”(请参阅下面的链接),但这两个工件仍在发布新版本:
https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-impl
这个答案在我的 Maven 项目中,哪些工件应该用于 JAXB RI? 没有阐明差异。
上述问题和这一问题的公认答案如何解决 java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException 的结论是,对于 Java 9+,您应该使用: org.glassfish.jaxb:jaxb-runtime
但我有使用 com.sun.xml.bind:jaxb-impl 的代码,它似乎工作正常。那么,迁移到 jaxb-runtime 会带来什么损失或收益呢?
即使是最新版本(我撰写本文时为 3.0.2)也可用于“旧”jaxb-impl 模块。如果 Oracle 不再这样做,那么谁制作了 com.sun.xml.bind:jaxb-impl 工件?它是做什么用的?为什么它不与 jaxb-runtime 共享 Maven 组坐标?
是否有任何中心位置可以清楚地记录 JAXB 的当前状况?
现在 JAXB 存在很多混乱。
PS 我暂时需要保持与 Java 8 的兼容性 - 所以我还不能使用 3.x,而 2.4.x 似乎是一次放弃的尝试,旨在修复他们在分离出来时愚蠢地破坏的模块化性。 JDK。
我在Windows环境中使用maven编译我的项目.虽然我刚刚创建了项目并添加了各种库的依赖项.
当我添加它们时,maven开始抱怨失踪tools.jar,所以我在下面添加到我的pom.xml:
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.6</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
Run Code Online (Sandbox Code Playgroud)
当我运行maven安装时,我得到了丢失jar的错误,如下所示:
[ERROR] Failed to execute goal on project GApp: Could not resolve dependencies for project GApp:GApp:war:0.0.1-SNAPSHOT: Could not find artifact com.sun:tools:jar:1.6 at specified path C:\Program Files\Java\jre6\lib\tools.jar -> [Help 1]
Run Code Online (Sandbox Code Playgroud)
问题是它tools.jar在" C:\Program Files\Java\jdk1.6.0_26\lib"中并且在JAVA_HOME环境变量中正确设置但是maven仍然在jre文件夹中查找错误消息" C:\Program Files\Java\jre6\lib\tools.jar".
C:\>echo %JAVA_HOME%
C:\Program Files\Java\jdk1.6.0_26
Run Code Online (Sandbox Code Playgroud)
有趣的是:当我设置依赖的完整路径时,它工作得很好.但我不想硬编码.
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.6</version>
<scope>system</scope>
<systemPath>C:\Program Files\Java\jdk1.6.0_26\lib\tools.jar</systemPath>
</dependency>
Run Code Online (Sandbox Code Playgroud)
有人可以建议任何动态解决方案吗?
[根据理解进展重编辑]
是否有可能让Spring Jaxb2Marshaller使用一组自定义的名称空间前缀(或者至少尊重模式文件/注释中给出的名称空间前缀),而不必使用NamespacePrefixMapper的扩展名?
我们的想法是让一个类与另一个类具有"has"关系,而另一个类又包含具有不同命名空间的属性.为了更好地说明这一点,请考虑以下使用JDK1.6.0_12的项目大纲(最新的我可以在工作中得到).我在org.example.domain包中有以下内容:
Main.java:
package org.example.domain;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class Main {
public static void main(String[] args) throws JAXBException {
JAXBContext jc = JAXBContext.newInstance(RootElement.class);
RootElement re = new RootElement();
re.childElementWithXlink = new ChildElementWithXlink();
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(re, System.out);
}
}
Run Code Online (Sandbox Code Playgroud)
RootElement.java:
package org.example.domain;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(namespace = "www.example.org/abc", name="Root_Element")
public class RootElement {
@XmlElement(namespace = "www.example.org/abc")
public ChildElementWithXlink childElementWithXlink;
}
Run Code Online (Sandbox Code Playgroud)
ChildElementWithXLink.java:
package org.example.domain;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchemaType;
@XmlRootElement(namespace="www.example.org/abc", …Run Code Online (Sandbox Code Playgroud) 该类com.sun.xml.bind.v2.model.annotation.AnnotationReader是jaxb-impl 2.1.6的一部分,但已在2.1.7中删除.有人知道为什么吗?
在Helios/m2eclipse下,当我生成jaxb源时,当我执行"更新项目配置"时,它们将被放在Eclipse源路径上.
Indigo/m2e(2011年6月22日首次发布)不会发生这种情况.我需要做些什么来解决这个问题?
我正在使用标准的maven-jaxb2-plugin,版本0.75.
我们尝试使用gradle,xsd和xjc生成JAXB类,而JAXB类应该具有XmlRootElement注释,因此它可以用于公开为Web服务响应.我们正在关注此链接http://azagorneanu.blogspot.com/2011/09/configure-maven-to-generate-classes.html,它有很大的帮助,但我们无法找到一个只有gradle的特定示例.所以我们想出了一些我们将分享的答案.
在什么情况下我需要在jaxb-implvs 之间做出选择jaxb-core?拥有jaxb-impl和jaxb-core我的项目中的两个会导致任何类加载冲突?
根据Oracle文档,schemagen工具已作为JEP 320(http://openjdk.java.net/jeps/320)的一部分从JDK中删除。JEP指出了现在提供缺少工具的Maven工件。在JEP中,工件的坐标是错误的,可以在以下问题的答案中找到更新的坐标: 我的Maven项目中应为JAXB RI使用哪些工件?
但是缺少的是如何调用工具。JEP中指向的Shell脚本位于JAXB-RI Git存储库中。但是,这些脚本仍然没有文档记录,很难调用。该git repo中的构建说明指示它是使用标准的“ mvn全新安装”构建的,但是不会产生与此处文档中使用的“ bin”文件夹相匹配的输出结构:https : //javaee.github.io /jaxb-v2/doc/user-guide/ch04.html#tools-schemagen
理想情况下,我想从Gradle运行schemagen,避免使用shell脚本,因为它们不是从maven依赖项获得的。
我当前的尝试是从一个称为旧schemagen.exe的工作版本改编而成,看起来像这样:
(“真实” build.gradle文件中还有更多内容可以指定我的应用程序的依赖关系,等等。)
configurations {
schemagenTool
}
dependencies {
schemagenTool "org.glassfish.jaxb:jaxb-jxc:${jaxbVersion}"
}
task schemaGen(type: Exec, dependsOn: [compileJava,configurations.schemaGenTool]) {
workingDir projectDir
executable 'java'
doFirst {
file('build/Schemas').mkdirs()
args '--module-path', "${configurations.schemaGenTool.asPath}",
'-m', 'jaxb.jxc/com.sun.tools.jxc.SchemaGeneratorFacade',
// Note: automatic module name is NOT com.sun.tool.jxc
// as documented
// Args to schemagen (these worked for the schemagen.exe)
'-d', 'build/Schemas',
'-classpath', "${compileJava.destinationDir}${File.pathSeparator}${configurations.compile.asPath}",
"src/main/java/path/to/my/ModelClass.java"
//println "\nschemagen: ${args.join(' ')}\n"
}
doLast {
// Above …Run Code Online (Sandbox Code Playgroud) 因此,我可以使用 ant xjc 从合同 jar 中的 ONE xsd 生成类。如何在不解压的情况下从这个 jar 的多个模式生成类
ant.xjc(package: packageName, destdir: project.ext.generatedSrcDir,
extension: 'true',
schema: "jar:file:///$pathToContractJar!/MySchema.xsd")
Run Code Online (Sandbox Code Playgroud)