Клиент Java SOAP WS выходит из командной строки, работает в Eclipse (шокирует, верно?)

#java #eclipse #maven #soap

Вопрос:

Я разрабатываю клиент WS, которому нужно будет использовать MTOM для передачи некоторых данных. Однако у меня другая проблема, и это сводит меня с ума. Это, конечно, включает в себя запуск файла JAR из командной строки.

Я использовал cxf-codegen-плагин для генерации классов из WSDL и создал простой клиент. Я создал макет сервиса в SoapUI с тем же WSDL и протестировал клиент на нем. Излишне говорить, что с Eclipse все работает идеально. Я использовал плагин maven-assembly-для создания одного JAR, и когда я запускаю его из командной строки, я получаю исключение следующим образом:

 java.lang.NullPointerException: Cannot invoke "org.apache.cxf.wsdl.WSDLManager.getDefinition(String)" because the return value of "org.apache.cxf.Bus.getExtension(java.lang.Class)" is null
       at org.apache.cxf.wsdl11.WSDLServiceFactory.<init>(WSDLServiceFactory.java:85)
       at org.apache.cxf.jaxws.ServiceImpl.initializePorts(ServiceImpl.java:217)
       at org.apache.cxf.jaxws.ServiceImpl.initialize(ServiceImpl.java:160)
       at org.apache.cxf.jaxws.ServiceImpl.<init>(ServiceImpl.java:129)
       at org.apache.cxf.jaxws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:82)
       at javax.xml.ws.Service.<init>(Service.java:112)
       at com.xxx.xmldefs.sup.enterpriseservices.documentmanagementservice.v1.DocumentManagementService.<init>(DocumentManagementService.java:43)
       at XXX.MTOMClient.MTOMClient.main(MTOMClient.java:53)
 

Очевидно, чего-то не хватает в моих зависимостях, пути сборки, библиотеках и тому подобном, так как из Eclipse клиент подключается, выполняет вызов и возвращает результат. Я проверил зависимости Maven и системные библиотеки Java в разделе «Порядок и экспорт» пути сборки проекта.

Чего мне не хватает? Я признаю, что не являюсь экспертом, я иногда разрабатываю что-то на Java, так что, возможно, это что-то простое, с чем я просто еще не сталкивался.

Заранее всем вам спасибо за вашу помощь!

Комментарии:

1. У вас есть все необходимые зависимости в вашем файле jar? Если вы его распакуете. Какую версию cxf вы используете?

2. Зависимости существуют, я не получаю исключение «ClassNotFound». Я использую v3.1.11 из CXF.

3. Что касается кода, то он не выполняет getBus().getExtension(WSDLManager.class) Как инициализируется ваша шина?

4. Я не делаю никакой явной инициализации в коде. Я создаю новый клиент веб-службы на основе классов, созданных CXF. Этот код отлично работает, когда я запускаю его в Eclipse, но завершается ошибкой, за исключением случая, описанного выше, когда я вызываю свою «толстую БАНКУ» из командной строки.

Ответ №1:

На случай, если кто-то еще столкнется с этой проблемой … проблема заключается в том, что создание fat JAR может привести к игнорированию различных файлов ссылок/конфигурации, если используется плагин maven-assembly. Это всегда приводит к одному, например META-INF/cfx/bus-extensions.txt файл, что в данном случае было проблемой.

Решение состоит в том, чтобы использовать плагин maven-shade, а затем применить трансформатор, называемый AppendingTransformer, к этому конкретному файлу. В Шейде есть несколько трансформаторов, которые могут понадобиться в вашем проекте. Ниже вы можете найти тот, который работал на меня:

     <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.2.4</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <mainClass>XXX.YYY.ZZZ</mainClass>
                </transformer>
                <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                  <resource>META-INF/cxf/bus-extensions.txt</resource>
                </transformer>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
              </transformers>
              <filters>
                <filter>
                  <artifact>*:*</artifact>
                  <excludes>
                    <exclude>META-INF/*.SF</exclude>
                    <exclude>META-INF/*.DSA</exclude>
                    <exclude>META-INF/*.RSA</exclude>
                  </excludes>
                </filter>
              </filters>
            </configuration>
          </execution>
        </executions>
    </plugin>
 

Раздел «Исключить» необходим для обработки подписанных банок, так как создание толстой БАНКИ сделает их недействительными, и JVM будет жаловаться.