build-helper-maven-plugin导致AnnotationTypeMismatchException

时间:2012-01-04 21:03:30

标签: java maven annotations jaxb

我正在使用JAXB从java类生成模式。反过来,模式由WSDL文档引用。例如,我有一个 common-ws-data项目 common-ws-data 项目包含“ FaultMessage ”对象;看起来像这样:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "FaultMessage",namespace="urn:ws.mycorp.com:common:faults", propOrder = {"message"})
public class FaultMessage {

@XmlElement(required = true, nillable = true)
protected String message;

/**
 * @return the message
 */
public String getMessage() {
    return message;
}

/**
 * @param message the message to set
 */
public void setMessage(String message) {
    this.message = message;
}

这通过JAXB生成模式;结果模式如下所示:

<xs:schema attributeFormDefault="qualified" elementFormDefault="qualified" version="1.0" targetNamespace="urn:ws.mycorp.com:common:faults" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="FaultMessage">
   <xs:sequence>
     <xs:element name="message" type="xs:string" nillable="true"/>
   </xs:sequence>
</xs:complexType>

到目前为止一切顺利。但是,我们想要对我们的模式和WSDL进行版本化,并且围绕Web的各种最佳实践建议建议将版本控制信息嵌入到命名空间中。所以...

urn:com.mycorp.ws:common:faults

会变成

urn:com.mycorp.ws:common:faults:1.3.1

显然,这意味着将注释修改为

 @XmlType(name = "FaultMessage",namespace="urn:ws.mycorp.com:common:faults:1.3.1", propOrder = {"message"})

但是,由于架构项目可能会变得非常大,因此每次版本更改时都必须更新所有域对象上的注释是不切实际的。所以我的想法是以某种方式从maven POM文件中提取版本信息,并将此值连接到默认命名空间。

为此,我编写了自己的maven插件,它将创建一个“ ProjectConstants ”类,它将各种maven项目属性公开为公共最终字符串字段;即:

public final class ProjectConstants {

public static final String ARTIFACT_ID="common-ws-data";
public static final String GROUP_ID="com.mycorp";
public static final String VERSION="1.3.1";

}

注释现在可以变为:

@XmlType(name = "FaultMessage",namespace="urn:ws.mycorp.com:common:faults:" + ProjectConstants.VERSION, propOrder = {"message"})

如果生成的ProjectConstants类与FaultMessage java文件放在同一个源路径中(即 src / main / java

,则可以正常工作

但是,如果我有我的插件,则在不同的源路径中生成 ProjectConstants 类;例如: / target / generated / maven ;然后通过 builder-helper-maven-plugin 将生成的源文件夹添加为额外的源文件夹,maven编译过程会以 AnnotationTypeMismatchException 进行破解。

这是builder-helper-maven-plugin的maven配置。相当标准,基本上:

<plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
        <version>1.7</version>
        <executions>
            <execution>
                <id>add-source</id>
                <phase>generate-sources</phase>
                <goals>
                    <goal>add-source</goal>
                </goals>
                <configuration>
                    <sources>
                        <source>target/generated/maven</source>
                    </sources>
                </configuration>
            </execution>
        </executions>
    </plugin>

以下是我们得到的例外情况:

Problem encountered during annotation processing; 
see stacktrace below for more information.
java.lang.annotation.AnnotationTypeMismatchException: Incorrectly typed data found for    annotation element public abstract java.lang.String    javax.xml.bind.annotation.XmlType.namespace() (Found data of type java.lang.String)
at com.sun.tools.apt.mirror.declaration.AnnotationProxyMaker$ValueVisitor$1.generateException(AnnotationProxyMaker.java:241)
at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:56)
at $Proxy3.namespace(Unknown Source)
at com.sun.xml.bind.v2.model.annotation.XmlTypeQuick.namespace(XmlTypeQuick.java:36)
at com.sun.xml.bind.v2.model.impl.TypeInfoImpl.parseTypeName(TypeInfoImpl.java:152)
at com.sun.xml.bind.v2.model.impl.ClassInfoImpl.<init>(ClassInfoImpl.java:169)
at com.sun.xml.bind.v2.model.impl.ModelBuilder.createClassInfo(ModelBuilder.java:339)
at com.sun.xml.bind.v2.model.impl.ModelBuilder.getClassInfo(ModelBuilder.java:239)
at com.sun.xml.bind.v2.model.impl.ModelBuilder.getClassInfo(ModelBuilder.java:209)
at com.sun.xml.bind.v2.model.impl.ModelBuilder.getTypeInfo(ModelBuilder.java:315)
at com.sun.xml.bind.v2.model.impl.ModelBuilder.getTypeInfo(ModelBuilder.java:330)
at com.sun.tools.xjc.api.impl.j2s.JavaCompilerImpl.bind(JavaCompilerImpl.java:90)
at com.sun.tools.jxc.apt.SchemaGenerator$1.process(SchemaGenerator.java:115)
at com.sun.mirror.apt.AnnotationProcessors$CompositeAnnotationProcessor.process(AnnotationProcessors.java:60)
at com.sun.tools.apt.comp.Apt.main(Apt.java:454)
at com.sun.tools.apt.main.JavaCompiler.compile(JavaCompiler.java:258)
at com.sun.tools.apt.main.Main.compile(Main.java:1102)
at com.sun.tools.apt.main.Main.compile(Main.java:964)
at com.sun.tools.apt.Main.processing(Main.java:95)
at com.sun.tools.apt.Main.process(Main.java:85)
at com.sun.tools.apt.Main.process(Main.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.tools.jxc.AptBasedTask$InternalAptAdapter.execute(AptBasedTask.java:97)
at com.sun.tools.jxc.AptBasedTask.compile(AptBasedTask.java:144)
at com.sun.tools.jxc.maven2.SchemaGenAdapter.execute(SchemaGenAdapter.java:111)
at com.sun.tools.jxc.maven2.SchemaGenMojo.execute(SchemaGenMojo.java:161)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:556)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:535)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:348)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)

[INFO] -------------------------------------------- ---------------------------- [错误]致命错误

我怀疑它是某种类加载器问题... @XmlType 注释的名称空间()属性的类型是java.lang.String;显然,“ urn:com.mycorp.ws:common:faults ”和 ProjectConstants.VERSION 的串联也是一个字符串;所以它原则上应该起作用;如果我将 ProjectConstants 放在 / src / main / java 中,它肯定有效。所以我怀疑发生了什么是 builder-helper-maven-plugin 以某种方式修改了类路径后, / src / main / java 已被读取;然后触发AnnotationTypeMismatchException。

关于如何解决这个问题的任何想法?

1 个答案:

答案 0 :(得分:0)

你使用com.sun.tools.xjc.maven2:maven-jaxb-plugin为什么你不调整执行顺序来编译你的接口然后运行jaxb编译器然后编译你最终的代码。

有一种更简单的方法:只需将界面移动到另一个jar(工件)并依赖它。所以编译顺序是自然的。

玩得开心。