Обновление трансляции XSD в Java: с Java 8/JAXB на Java 17/Jakarta

Вопрос или проблема

Я испытываю трудности с обновлением существующей сборки gradle на Java 8 и JAXB, которая генерирует Java-объекты из XSD, чтобы перейти на Java 17 и Jakarta. Как мне обновить следующую задачу gradle для использования Jakarta? Существует ли задача XJC для Jakarta? Я не могу найти на нее ссылку.

Вот мой build.gradle:

plugins {
    id 'java'
}

defaultTasks 'clean', 'compileJava'

project.ext {
    jaxbTargetDir = "xsd_src"
    schemaSrc = "xsd_v1.0"
    schemaName = "schema_20180419.xsd"
}

sourceSets {
    main {
        // используйте сгенерированный ant исходный код и дополнительный источник
        java { 
            srcDir "${jaxbTargetDir}"
            srcDir 'extra_src'
        }
        // включите исходный код в jar
        resources {
            srcDir "${schemaSrc}"
        }
    }
}

tasks.withType(JavaCompile).configureEach {
    options.fork = true  // Запустите компиляцию в дочернем процессе
    options.forkOptions.setMemoryMaximumSize("4g") // Установите максимальную память на 4g
}

configurations {
    xsd2Java
}

dependencies {      
    // Зависимости Java EE
    xsd2Java('jakarta.xml.bind:jakarta.xml.bind-api:4.0.0')
    xsd2Java('jakarta.activation:jakarta.activation-api:2.0.0')
    xsd2Java('jakarta.annotation:jakarta.annotation-api:2.1.0-B1')

    implementation 'org.javassist:javassist:3.29.0-GA'

    // Версии приходят из Maven Jaxb2 Plugin   
    implementation 'org.jvnet.jaxb:jaxb2-basics:2.0.5'
    implementation 'org.jvnet.jaxb:jaxb2-basics-ant:2.0.5'
    implementation 'org.jvnet.jaxb:jaxb-basics-annotate:2.0.5'
    implementation 'org.jvnet.jaxb:jaxb2-basics-runtime:2.0.5'

    implementation 'org.glassfish.jaxb:jaxb-runtime:4.0.1'
    implementation 'org.glassfish.jaxb:jaxb-xjc:4.0.0-M4'

    compileOnly 'org.slf4j:slf4j-simple:1.7.28'
}

task xsd2Java() {
    doLast {          
        ant.taskdef(name: 'xjc', classname: 'org.jvnet.jaxb2_commons.xjc.XJC2Task', classpath: configurations.compileClasspath.asPath)
        ant.jaxbTargetDir = file("${jaxbTargetDir}")

        ant.xjc(
            extension: true,
            destdir: '${jaxbTargetDir}',
            binding: file("${schemaSrc}/bindingsv.xjb"),

        ) {
            schema(dir: "${schemaSrc}") {
                include(name: "${schemaName}")
            }
            arg(line: "-nv -extension -xmlschema -Xannotate -XtoString -Xequals -XhashCode -Xcopyable")
            // проверьте временные метки на xsds и java файлах, чтобы увидеть, нужно ли нам регенерировать
            depends(dir: "${schemaSrc}") {
                include(name: "**/*.xsd")
            }
            produces(dir: "${jaxbTargetDir}") {
                include(name: "**/*.java")
            }
        }
    }
}

compileJava.dependsOn 'xsd2Java'

Я также обновил bindingsv.xjb, чтобы ссылаться на jakarta:

<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings
    xmlns:jxb="https://jakarta.ee/xml/ns/jaxb"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xjc="https://jakarta.ee/xml/ns/jaxb/xjc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:annox="http://annox.dev.java.net"
    xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd 
                    http://annox.dev.java.net"
    jxb:extensionBindingPrefixes="annox xjc" version="3.0">

Однако, когда я запускаю сборку, я получаю эту ошибку:

Execution failed for task ':Services:messages:xsd2Java'.
> java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

Буду признателен за любые советы или предложения!

Ответ или решение

Чтобы обновить вашу сборку Gradle от Java 8/JAXB до Java 17/Jakarta, необходимо внести несколько изменений как в зависимости, так и в задачи. Давайте детально рассмотрим, что необходимо сделать.

Шаг 1: Обновление зависимостей

Вам необходимо убедиться, что вы используете правильные версии зависимостей для Jakarta. Вот обновлённый файл build.gradle, который учитывает ваши требования:

plugins {
    id 'java'
}

defaultTasks 'clean', 'compileJava'

project.ext {
    jaxbTargetDir = "xsd_src"
    schemaSrc = "xsd_v1.0"
    schemaName = "schema_20180419.xsd"
}

sourceSets {
    main {
        // Используем директории для сгенерированного кода и дополнительные источники
        java { 
            srcDir "${jaxbTargetDir}"
            srcDir 'extra_src'
        }
        // Включаем ресурсы в jar
        resources {
            srcDir "${schemaSrc}"
        }
    }
}

tasks.withType(JavaCompile).configureEach {
    options.fork = true  // Запуск компиляции в отдельном процессе
    options.forkOptions.setMemoryMaximumSize("4g") // Максимальный объём памяти
}

configurations {
    xsd2Java
}

dependencies {
    // Зависимости для Jakarta EE
    xsd2Java('jakarta.xml.bind:jakarta.xml.bind-api:3.0.0') // Обратите внимание на обновлённую версию
    xsd2Java('jakarta.activation:jakarta.activation-api:2.0.0')
    xsd2Java('jakarta.annotation:jakarta.annotation-api:2.1.0')

    implementation 'org.javassist:javassist:3.29.0-GA'

    // Зависимости от JAXB
    implementation 'org.glassfish.jaxb:jaxb-runtime:3.0.0'
    implementation 'org.glassfish.jaxb:jaxb-xjc:3.0.0'

    compileOnly 'org.slf4j:slf4j-simple:1.7.28'
}

task xsd2Java() {
    doLast {
        ant.taskdef(name: 'xjc', classname: 'com.sun.tools.xjc.exe.Main', classpath: configurations.xsd2Java.asPath)
        ant.jaxbTargetDir = file("${jaxbTargetDir}")

        ant.xjc(
            extension: true,
            destdir: "${jaxbTargetDir}",
            binding: file("${schemaSrc}/bindingsv.xjb"),
        ) {
            schema(dir: "${schemaSrc}") {
                include(name: "${schemaName}")
            }
            arg(line: "-nv -extension -xmlschema -Xannotate -XtoString -Xequals -XhashCode -Xcopyable")
            depends(dir: "${schemaSrc}") {
                include(name: "**/*.xsd")
            }
            produces(dir: "${jaxbTargetDir}") {
                include(name: "**/*.java")
            }
        }
    }
}

compileJava.dependsOn 'xsd2Java'

Шаг 2: Обновление файла XJB

Убедитесь, что ваш файл bindingsv.xjb правильно использует пространства имен и версии для Jakarta. Например:

<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings
    xmlns:jxb="http://xmlns.jcp.org/xml/ns/jaxb"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xjc="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:annox="http://annox.dev.java.net"
    jxb:extensionBindingPrefixes="annox xjc" 
    version="2.1">
    <!-- ваши настройки и привязки -->
</jxb:bindings>

Шаг 3: Исправление ошибок

Ошибка java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException возникает из-за отсутствия библиотеки Jakarta в classpath. Убедитесь, что вы используете jakarta.xml.bind:jakarta.xml.bind-api версии 3.0.0, так как это правильная версия для Jakarta. Также убедитесь, что ваша версия jaxb-runtime соответствует этому API.

Шаг 4: Запуск сборки

Теперь, когда вы сделали все необходимые изменения, попробуйте выполнить команду сборки снова:

./gradlew clean build

В случае продолжения возникновения ошибок, проверьте, что все зависимости загружаются корректно и что класс com.sun.tools.xjc.exe.Main действительно находится в classpath. Возможно, вам потребуется установить Java SE Development Kit, если xjc не подключен.

Если потребуется дополнительная помощь, пожалуйста, не стесняйтесь обращаться.

Оцените материал
Добавить комментарий

Капча загружается...