2015-01-16 32 views
5

Tôi có một ứng dụng JAX-RS CXF được xây dựng với Maven. Tôi đang làm việc để chuyển đổi nó thành Gradle, nhưng sử dụng tác vụ Ant XJC.com.sun.tools.xjc.Plugin: Provider <plugin> không một subtype

Phiên bản hiện tại sử dụng một vài tiện ích mở rộng, một trong số đó là bản sao của trình bao bọc phần tử "" và phần còn lại là "jaxb-fluent-api".

Tôi đã thử đặt các lọ cho hai plugins vào classpath XJC, nhưng khi tôi chạy nhiệm vụ XJC, tôi nhận được như sau:

lớp

java.util.ServiceConfigurationError: com.sun.tools.xjc.Plugin: Provider dk.conspicio.jaxb.plugins.XmlElementWrapperPlugin not a subtype

Các XmlElementWrapperPlugin kéo dài "com.sun.tools.xjc .Cắm vào".

Bất kỳ ý tưởng những gì đang xảy ra ở đây?

Nếu vấn đề, cấu hình Maven của tôi cho các plugin XJC trông giống như sau:

<plugin> 
    <groupId>org.apache.cxf</groupId> 
    <artifactId>cxf-xjc-plugin</artifactId> 
    <executions> 
     <execution> 
      <id>generate-sources</id> 
      <phase>generate-sources</phase> 
      <goals> 
       <goal>xsdtojava</goal> 
      </goals> 
      <configuration> 
       <extensions> 
        <extension>JAXBXMLElementWrapperPlugin:JAXBXMLElementWrapperPlugin:1.0.0</extension> 
        <extension>net.java.dev.jaxb2-commons:jaxb-fluent-api:2.1.8</extension> 
       </extensions> 
       <xsdOptions> 
        <xsdOption> 
         <xsd>${basedir}/src/main/resources/schema/serviceCallResults.xsd</xsd> 
         <packagename>com.att.sunlight.service.domain.serviceCallResults</packagename> 
         <extension>true</extension> 
         <extensionArgs> 
          <extensionArg>-Xxew</extensionArg> 
          <extensionArg>-summary ${basedir}/target/xew-summary.txt</extensionArg> 
          <extensionArg>-instantiate lazy</extensionArg> 
          <extensionArg>-Xfluent-api</extensionArg> 
         </extensionArgs> 
        </xsdOption> 
       </xsdOptions> 
      </configuration> 
     </execution> 
    </executions> 
</plugin> 

Dưới đây là tôi "build.gradle", chỉ với các kho elided:

apply plugin: 'java' 
apply plugin: 'maven' 
apply plugin: 'war' 

group = 'SunlightDataService' 
version = '1.2.4-SNAPSHOT' 

sourceCompatibility = 1.6 
targetCompatibility = 1.6 

repositories { 
    ... 
} 

configurations { 
    jaxb 
} 

dependencies { 

    jaxb 'com.sun.xml.bind:jaxb-xjc:2.2.7-b41' 
    jaxb 'com.sun.xml.bind:jaxb-impl:2.2.7-b41' 
    jaxb 'javax.xml.bind:jaxb-api:2.2.7' 
    jaxb "JAXBXMLElementWrapperPlugin:JAXBXMLElementWrapperPlugin:1.0.0" 
    jaxb "net.java.dev.jaxb2-commons:jaxb-fluent-api:2.1.8" 

    compile group: 'org.springframework', name: 'spring-beans', version:'3.2.8.RELEASE' 
    compile group: 'org.springframework', name: 'spring-webmvc-portlet', version:'3.2.8.RELEASE' 
    compile group: 'org.apache.cxf', name: 'cxf-rt-transports-http', version:'2.7.7' 
    compile group: 'log4j', name: 'log4j', version:'1.2.16' 
    compile group: 'org.springframework', name: 'spring-jdbc', version:'3.2.8.RELEASE' 
    compile group: 'org.springframework', name: 'spring-context', version:'3.2.8.RELEASE' 
    compile group: 'org.apache.cxf', name: 'cxf-rt-frontend-jaxrs', version:'2.7.7' 
    compile group: 'org.apache.cxf', name: 'cxf-rt-bindings-xml', version:'2.7.7' 
    compile group: 'org.apache.cxf', name: 'cxf-rt-databinding-jaxb', version:'2.7.7' 
    compile group: 'org.apache.cxf', name: 'cxf-rt-core', version:'2.7.7' 
    compile group: 'org.apache.cxf', name: 'cxf-api', version:'2.7.7' 
    compile group: 'org.apache.cxf', name: 'cxf-rt-rs-extension-providers', version:'2.7.7' 
    compile group: 'org.codehaus.jettison', name: 'jettison', version:'1.3.4' 
    compile group: 'org.perf4j', name: 'perf4j', version:'0.9.14' 
    compile group: 'cglib', name: 'cglib', version:'2.2.2' 
    compile group: 'org.aspectj', name: 'aspectjweaver', version:'1.6.12' 
    compile group: 'commons-collections', name: 'commons-collections', version:'3.2.1' 
    compile group: 'esGateKeeper', name: 'GLCookieDecryption', version:'1.0.0' 
    compile group: 'joda-time', name: 'joda-time', version:'2.3' 
    compile group: 'org.apache.jackrabbit', name: 'jackrabbit-core', version:'2.4.0' 
    compile group: 'org.apache.commons', name: 'commons-lang3', version:'3.1' 
    testCompile group: 'org.springframework', name: 'spring-test', version:'3.2.8.RELEASE' 
    testCompile group: 'oracle.jdbc', name: 'oracle.jdbc.OracleDriver', version:'1.0.0' 
    testCompile group: 'com.atomikos', name: 'transactions-jta', version:'3.7.0' 
    testCompile group: 'org.apache.cxf', name: 'cxf-rt-transports-http-jetty', version:'2.7.7' 
    testCompile group: 'com.atomikos', name: 'transactions-jdbc', version:'3.7.0' 
    testCompile group: 'org.mockito', name: 'mockito-all', version:'1.9.5' 
    testCompile group: 'junit', name: 'junit', version:'4.10' 
    testCompile group: 'org.assertj', name: 'assertj-core', version:'1.6.1' 
    providedCompile group: 'javax.transaction', name: 'jta', version:'1.1' 
    providedCompile group: 'javax.servlet.jsp', name: 'jsp-api', version:'2.1' 
    providedCompile group: 'javax.servlet', name: 'servlet-api', version:'2.5' 
} 

task processXSDs() << { 
    ant.taskdef(name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask', 
       classpath: configurations.jaxb.asPath) 

    ant.xjc(destdir: 'tmp', package: "com.att.sunlight.service.domain.serviceCallResults", extension: true) { 
     schema(dir: "src/main/resources/schema", includes: "serviceCallResults.xsd") 
     arg(line: "-Xxew") 
     arg(line: "-summary target/xew-summary.txt") 
     arg(line: "-instantiate lazy") 
     arg(line: "-Xfluent-api") 
    } 
} 

compileJava.dependsOn processXSDs 

Cập nhật:

tôi đã xác định rằng đây không phải là một vấn đề với phần mở rộng "Yếu tố Wrapper". Nếu tôi xóa lọ đó khỏi đường dẫn lớp và xây dựng lại, nó báo cáo lỗi tương tự cho plugin "Fluent API".

Tôi cũng đã xác định đây không phải là một vấn đề nghiêm Gradle. Tôi nhận được cùng một triệu chứng với một Ant "build.xml", và thậm chí một kịch bản shell đơn giản trực tiếp gọi lớp Java "XJCFacade". Trong thực tế, tôi có thể đơn giản hóa kịch bản này một chút bằng cách thậm chí không chỉ định bất kỳ tệp lược đồ nào, làm cho nó rõ ràng lỗi này xảy ra ngay cả trước khi cố xử lý bất kỳ lược đồ nào.

Sau đây là kịch bản hiện tại của tôi:

#! /bin/bash 
java -classpath "lib/commons-beanutils-1.7.0.jar;lib/commons-lang-2.2.jar;lib/commons-logging-1.1.1.jar;lib/istack-commons-runtime-2.16.jar;lib/jaxb2-basics-runtime-0.6.5.jar;lib/jaxb2-basics-tools-0.6.5.jar;lib/jaxb-api-2.2.7.jar;lib/jaxb-core-2.2.7.jar;lib/jaxb-fluent-api-2.1.8.jar;lib/jaxb-xew-plugin-1.4.jar;lib/jaxb-xjc-2.2.7.jar" com.sun.tools.xjc.XJCFacade -extension 

Bạn có thể xây dựng các thử nghiệm tương tự bằng cách tải về tất cả những hiện vật để bộ nhớ cache Gradle hoặc Maven của bạn và sao chép chúng vào một cấu trúc thư mục đơn giản.

Cũng lưu ý rằng tôi đang chạy thử nghiệm này chủ yếu là trên Windows 7, nhưng tôi nén lên dự án này và di chuyển nó đến CentOS VM của tôi và nó mang lại cho tôi những lỗi chính xác tương tự.

+0

Bạn có thể đăng thêm build.grade của mình không? Ít nhất là khối 'dependencies {...}'. –

+0

Bản sửa đổi mới có toàn bộ tập lệnh, ngoại trừ các kho lưu trữ. –

+0

Thử thay thế 'arg (dòng:" ... ")' bằng 'arg (giá trị:" ... ")'. –

Trả lời

10

Tôi đã thử

java -cp jaxb-api-2.2.7.jar;jaxb-core-2.2.7.jar;jaxb-xjc-2.2.7.jar;commons-logging-1.1.1.jar;commons-lang-2.2.jar;jaxb2-basics-tools-0.6.5.jar;jaxb-xew-plugin-1.3.jar com.sun.tools.xjc.XJCFacade -verbose -extension -d src xsd

và thực sự mà không thành công với Exception in thread "main" java.util.ServiceConfigurationError: com.sun.tools.xjc.Plugin: Provider com.sun.tools.xjc.addon.xew.XmlElementWrapperPlugin not a subtype, vì vậy vấn đề rõ ràng là tái sản xuất. Tôi đã gỡ lỗi java.util.ServiceLoader và nó bật ra rằng các plugin nên được thông qua như là đối số để XJC (không phải classpath của Java). Trên thực tế, tất cả các plugin maven (như jaxb2-maven-plugin hoặc maven-jaxb2-plugin…) biết về tính năng này và biểu mẫu XJC tranh luận chính xác. Vì vậy, các dòng lệnh đúng là:

java -cp jaxb-api-2.2.7.jar;jaxb-core-2.2.7.jar;jaxb-xjc-2.2.7.jar;commons-lang-2.2.jar;commons-logging-1.1.1.jar com.sun.tools.xjc.XJCFacade -classpath jaxb-xew-plugin-1.3.jar;jaxb2-basics-tools-0.6.5.jar -verbose -extension -Xxew -d src xsd

Lưu ý rằng -classpath là lập luận cho XJC. commons-xxx libs có thể đi đến classpath hệ thống như các gói mà họ xuất khẩu không được sàng lọc, nhưng jaxb2-basics-tools phải ở trong classpath XJC.Nếu bạn quan tâm đến chi tiết:

Điều này xảy ra vì XJC thực hiện sàng lọc bộ tải lớp để có thể tải các phiên bản cao hơn của API JAXB trong JRE có phiên bản API tích hợp thấp hơn. Xem XJCFacade.java line 69. Điều đó có nghĩa là com.sun.tools.xjc.Plugin được tải một lần bởi bộ nạp lớp tùy chỉnh XJCFacade trong khi cùng một lớp được nạp bởi trình nạp lớp khác (thực sự, cha mẹ) một lần nữa khi gọi Class.forName("com.sun.tools.xjc.addon.xew.XmlElementWrapperPlugin"), nhưng bây giờ các lớp không bằng nhau.

Trên thực tế bạn có thể workaround như thế này (giải pháp phát hiện sau khi kiểm tra mã nguồn):

java -Dcom.sun.tools.xjc.XJCFacade.nohack=true -cp jaxb-core-2.2.7.jar;jaxb-xjc-2.2.7.jar;commons-lang-2.2.jar;commons-logging-1.1.1.jar;jaxb2-basics-tools-0.6.5.jar;jaxb-xew-plugin-1.3.jar com.sun.tools.xjc.XJCFacade -verbose -extension -Xxew -d src xsd

Lưu ý rằng tôi đã xoá jaxb-api-2.2.7.jar từ Java classpath nhưng bạn nên đặt JAXB API vào lib/endorsed vì nó có thể không hoạt động trên các phiên bản Java khác nhau: hoạt động tốt cho Java 7, bởi vì it's JAXB API is close to 2.2.7, nhưng có thể không hoạt động trên Java 6 + JAXB API 2.2.11.

+3

Rất ấn tượng. – lexicore

+0

Để tóm tắt các giải pháp cho điều này, tôi đang cố gắng để characterize classpath cần thiết để "tham khảo" XJC như trái ngược với "chạy" XJC. Có hợp lý để tách chúng ra khỏi các điều khoản này không? Ví dụ, các lọ XJC chính là cần thiết để "tham chiếu" XJC, nhưng các lọ mở rộng cần phải ở trong classpath "đang chạy". Tôi nghĩ rằng việc gọi phần thứ hai "chạy" có phần hợp lý, nhưng gọi phần "tham khảo" khác có thể không hoàn toàn đúng. –

+0

Có lẽ "tham chiếu" nên được gọi là "khởi tạo" tốt hơn, nhưng về mặt khái niệm bạn nói đúng: các plugin nên được quảng bá cho classpath "khác". –

-1

Không có kỹ sư xây dựng/phát hành hoặc trình cài đặt jaxb-xjc nào buộc phải sử dụng Trình nạp lớp JAXB-JXC độc quyền nội bộ. Thiết kế ban đầu là vì vậy người dùng JDK 1.x sẽ không tải JAXB-2.2.0.jar .. từ năm 2010 đã không có thay đổi đáng kể về phiên bản cho JAXB và các nhà phát triển jaxb-xjc đã ngừng duy trì plugin này cho JDK 5,6, 7,8. Tôi đã gửi một email đến các chuyên gia của Oracle tại CXF-Metro vào ngày 31 tháng 1. Nếu chúng tôi không nhận được phản hồi từ họ, hãy yêu cầu Oracle phát hành mã cho OpenSource để ít nhất nó sẽ được duy trì. Mọi trình cài đặt của plugin này đều bị vấp phải bởi giải pháp tạm thời này. Không cần phải tiếp tục trừng phạt những người triển khai trong tương lai với mã không rõ ràng bị hack ngắn hạn. Cũng tùy chọn -DClassLoaderBuilder.noHack Hoàn toàn bỏ qua Oracles sở hữu an Manager..this là verboten trong ngân hàng và tổ chức tài chính ... tôi sẽ đăng lại khi tôi nghe lại từ CXF Metro

+0

Bất kỳ tin tức nào? * [15chars] * – Alix

3

Kudos để dma_k, nhưng một giải pháp làm việc gradle không bao giờ được cung cấp. Sau một số thử nghiệm, đây là những gì làm việc cho tôi:

def xjcGeneratedSourcesDir = "$buildDir/generated-sources/xjc" 

configurations { 
    jaxb 
    xjc 
} 

sourceSets { 
    main { 
     java.srcDir xjcGeneratedSourcesDir 
    } 
} 

dependencies { 
    jaxb 'com.sun.xml.bind:jaxb-xjc:2.2.11' 
    jaxb 'com.sun.xml.bind:jaxb-core:2.2.11' 
    jaxb 'com.sun.xml.bind:jaxb-impl:2.2.11' 
    jaxb 'javax.xml.bind:jaxb-api:2.2.11' 

    xjc "com.github.jaxb-xew-plugin:jaxb-xew-plugin:1.4" 
    xjc "net.java.dev.jaxb2-commons:jaxb-fluent-api:2.1.8" 

    // etc. 
} 

task wsdl2java << { 
    file(xjcGeneratedSourcesDir).mkdirs() 

    ant.taskdef(name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask', 
       classpath: configurations.jaxb.asPath) 

    ant.xjc(destdir: xjcGeneratedSourcesDir, 
      package: "com.localhost.jaxb", extension: true) { 
     schema(dir: "src/main/resources/schema", includes: "*.xsd") 
     classpath(path: configurations.xjc.asPath) 
     arg(line: "-Xxew") 
     arg(line: "-Xxew:summary $buildDir/xew-summary.txt") 
     arg(line: "-Xxew:instantiate lazy") 
     arg(line: "-Xfluent-api") 
    } 
} 

compileJava.dependsOn wsdl2java 
+0

Xin lỗi, tôi đã quên thêm thông tin vào điều này. Tôi cũng đã kết thúc với một giải pháp tương tự, gần như chính xác trong thực tế. Tôi thấy rằng tôi không cần phải chỉ định rõ ràng sự phụ thuộc "jaxb-impl". Tôi đã định nghĩa phiên bản "xjcGeneratedSourcesDir" của mình trong một khối "ext", giống như Gradle hơn, và tôi cũng đặt lệnh gọi "ant.xjc" của mình theo một phương thức mà tôi gọi nhiều lần với các lược đồ cụ thể để xử lý. –

+0

Cảm ơn. Nó làm việc cho tôi. – dpg

Các vấn đề liên quan