Wildfly: Как использовать JAXWS-RI вместо Apache CXF (только клиент WebService)

Моя среда - это проект Maven и Wildfly (8.2.1) в качестве сервера приложений. Что мне нужно, так это подключить входящий вызов REST к стороннему серверу с помощью SOAP. Мне нужна аутентификация клиента SSL; поэтому у меня есть свой собственный KeyStore и TrustStore. Поэтому я создаю свой собственный SSLContext и должен позволить WebService использовать этот SSLContext.

Все выглядит так:

// Build SSL context with own KeyManager / TrustManager
SSLContext sc = SSLContext.getInstance("TLS");

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());

KeyStore ks = KeyStore.getInstance("JKS");
String password = "changeit";
ks.load(getClass().getResourceAsStream("/keystore"), password.toCharArray());

kmf.init(ks, password.toCharArray());

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);

sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

// Now build webservice client
MyWS_Service service = new MyWS_Service(null, new QName("http://...", "MyWS"));
MyWS port = service.getMyWSSOAP();

BindingProvider bindingProvider = (BindingProvider) port;

// set to use own SSLContext
bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", sc.getSocketFactory());
// set endpoint
bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://hostname:443/.../...");

// perform request
respObj = port.myRequest(myRequestObj);

Если я вызываю этот код из теста JUnit, все работает нормально. Он использует JAXWS-RI из JRE.

Если я вызываю этот код из Wildfly, то есть из моего входящего вызова REST, где мне, наконец, нужно запустить этот запрос, он не работает, потому что он не использует собственный SSLContext. Он использует SSLContext по умолчанию, который, конечно, отклоняется сторонним SOAP-сервером. Я вижу, что он не использует JAXWS-RI, а Apache CXF в качестве реализации JAXWS. Так что я думаю, чтоbindingProvider.getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", sc.getSocketFactory()); просто игнорируется [Зачем?] и не имеет никакого эффекта. (Я также попробовал имя свойстваcom.sun.xml.ws.transport.https.client.SSLSocketFactory [безinternal] - тоже не повезло.)

Я знаю, что я мог бы использоватьHttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()) или даже использовать параметры JVMjavax.net.ssl.trustStore, javax.net.ssl.keyStore (и соответствующие им свойства пароля). Поскольку это влияет на все соединения, использование данного решения не подлежит обсуждению; однако, давайте посмотрим, что произойдет, если я все равно буду его использовать:

Случай использования JUnit: это также работает

Случай использования Wildfly: Кажется, что JAXWS принимает SSLContext, но есть исключение SSL (предупреждение от сервера о том, что CA неизвестен). Это показывает, что есть даже разница в том, как установить соединение. Почему это работает, если код выполняется с помощью JUnit? Это доказывает, что KeyStore / TrustStore правильно настроен с правильными сертификатами. Не так ли?

Редактировать: Есть еще одно доказательство того, что проблема заключается в реализации JAXWS, которую использует Wildfly: если я просто выполняю простое соединение HttpsConnection, он даже работает с моим собственным KeyStore / TrustStore в Wildfly:

url = new URL("https://hostname:443/.../...");
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setSSLSocketFactory(sc.getSocketFactory());
System.out.println(Utils.inputStreamToString(con.getInputStream()));

Так что лучше всего сделать? -> В качестве заголовков вопросов я хотел бы попытаться заставить Wildfly также использовать JAXWS-RI, а не Apache CXF. Но я получил это не работать до сих пор. Я попытался поставить следующую зависимость в пом:

    <dependency>
        <groupId>com.sun.xml.ws</groupId>
        <artifactId>jaxws-rt</artifactId>
        <version>2.2.10</version>
    </dependency>

Но это дает мне следующее исключение:

java.util.ServiceConfigurationError: javax.xml.ws.spi.Provider: Provider com.sun.xml.ws.spi.ProviderImpl could not be instantiated
    at java.util.ServiceLoader.fail(ServiceLoader.java:232) ~[?:1.8.0_92]

Что случилось? Как я могу заставить Wildfly работать так же, как если бы код выполнялся из того же проекта, но "как тест JUnit"?

Редактировать: Если у вас есть совет, как достичь цели (отправка SOAP-запросов с использованием SSL с аутентификацией клиента в Wildfly 8.2.1) другим способом (при условии, что это чистое решение Java EE - т.е. не отправка собственных тел XML :-) и не со слишком старыми каркасами, такими как Axis 1), это также приветствуетсяМне нужно решение в ближайшее время - я борюсь уже несколько дней ...

Ответы на вопрос(3)

Ваш ответ на вопрос