How to configure SSL with Axis2 using httpClient4 - ssl

Since the httpClient 3 has been outdated, I need a replacement for the code:
SSLProtocolSocketFactory.setSSL(trustStore, keyStore, pasw);
ProtocolSocketFactory factory = new SSLProtocolSocketFactory();
Protocol.registerProtocol("https", new Protocol("https", factory, 443));
Please share if anyone has tried it.
In the java code, I'm tring to call the webservice using OperationClient object
operationClientObject.execute(true);
Thanks in advance..

The axis2 httpclient4 migration is not so easy, as it appears from the "documentation".
During the process, I use the latest Axis 2 version 1.7.8.
The axis 2 1.7.0 release notes contains a one liner, for HttpClient v4 integration:
Axis2 1.7.0 supports Apache HttpClient 4.x in addition to the no longer maintained Commons HttpClient 3.x. To enable the support for HttpClient 4.x, use org.apache.axis2.transport.http.impl.httpclient4.HTTPClient4TransportSender instead of org.apache.axis2.transport.http.CommonsHTTPTransportSender in axis2.xml. Please note that the code was written for HttpClient 4.2.x and should work with 4.3.x and 4.4.x, but is incompatible with 4.5.x.
Watch out the last words. Axis 2 1.7.8 pom file, and the binary distribution contains the httpclient-4.5.3.jar, but doesn't work with it. So use httpclient 4.4.1 instead.
Enable logging
Before the upgrade, I suppose you already have a working axis 2 project. I recommend to enable axis 2 debug logging, to see what happens. To enable logging define a custom log4j propery file with jvm argument:
-Dlog4j.configuration=file:/c:/work/sources/debug_log4j.properties
The content of the debug_log4j.properties file is:
log4j.rootCategory=DEBUG, CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[%p] %m%n
Axis2 + Httpclient4
If you doesn't have axis2.xml, you can found it in axis2 binary package (contains all the dependencies and example configs)
Based on the release notes, you need to change the transport senders from CommonsHTTPTransportSender to HTTPClient4TransportSender.
If you look (or debug) axis2 configurator, you see, the xml must contain specific parts otherwise axis2 doesn't read it.
So my axis2.xml content after configured to use HttpClient4 (and removed unused parts, but keep essential ones):
<axisconfig name="AxisJava2.0">
<!-- ================================================= -->
<!-- Transport Outs -->
<!-- ================================================= -->
<parameter name="hotdeployment">true</parameter>
<parameter name="hotupdate">false</parameter>
<parameter name="enableMTOM">false</parameter>
<parameter name="enableSwA">false</parameter>
<transportSender name="local"
class="org.apache.axis2.transport.local.LocalTransportSender"/>
<transportSender name="http"
class="org.apache.axis2.transport.http.impl.httpclient4.HTTPClient4TransportSender">
<parameter name="PROTOCOL">HTTP/1.1</parameter>
<parameter name="Transfer-Encoding">chunked</parameter>
<!-- If following is set to 'true', optional action part of the Content-Type will not be added to the SOAP 1.2 messages -->
<!-- <parameter name="OmitSOAP12Action">true</parameter> -->
</transportSender>
<transportSender name="https"
class="org.apache.axis2.transport.http.impl.httpclient4.HTTPClient4TransportSender">
<parameter name="PROTOCOL">HTTP/1.1</parameter>
<parameter name="Transfer-Encoding">chunked</parameter>
</transportSender>
<!-- ================================================= -->
<!-- Phases -->
<!-- ================================================= -->
<phaseOrder type="InFlow">
<!-- System predefined phases -->
<phase name="Transport">
<handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher">
<order phase="Transport"/>
</handler>
<handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher">
<order phase="Transport"/>
</handler>
</phase>
<phase name="Addressing">
<handler name="AddressingBasedDispatcher"
class="org.apache.axis2.dispatchers.AddressingBasedDispatcher">
<order phase="Addressing"/>
</handler>
</phase>
<phase name="Security"/>
<phase name="PreDispatch"/>
<phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
<handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher"/>
<handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher"/>
<handler name="RequestURIOperationDispatcher"
class="org.apache.axis2.dispatchers.RequestURIOperationDispatcher"/>
<handler name="SOAPMessageBodyBasedDispatcher"
class="org.apache.axis2.dispatchers.SOAPMessageBodyBasedDispatcher"/>
<handler name="HTTPLocationBasedDispatcher"
class="org.apache.axis2.dispatchers.HTTPLocationBasedDispatcher"/>
<handler name="GenericProviderDispatcher"
class="org.apache.axis2.jaxws.dispatchers.GenericProviderDispatcher"/>
<handler name="MustUnderstandValidationDispatcher"
class="org.apache.axis2.jaxws.dispatchers.MustUnderstandValidationDispatcher"/>
</phase>
<phase name="RMPhase"/>
<!-- System predefined phases -->
<!-- After Postdispatch phase module author or service author can add any phase he want -->
<phase name="OperationInPhase">
<handler name="MustUnderstandChecker"
class="org.apache.axis2.jaxws.dispatchers.MustUnderstandChecker">
<order phase="OperationInPhase"/>
</handler>
</phase>
<phase name="soapmonitorPhase"/>
</phaseOrder>
<phaseOrder type="OutFlow">
<!-- user can add his own phases to this area -->
<phase name="soapmonitorPhase"/>
<phase name="OperationOutPhase"/>
<!--system predefined phase-->
<!--these phase will run irrespective of the service-->
<phase name="RMPhase"/>
<phase name="PolicyDetermination"/>
<phase name="MessageOut"/>
<phase name="Security"/>
</phaseOrder>
<phaseOrder type="InFaultFlow">
<phase name="Addressing">
<handler name="AddressingBasedDispatcher"
class="org.apache.axis2.dispatchers.AddressingBasedDispatcher">
<order phase="Addressing"/>
</handler>
</phase>
<phase name="Security"/>
<phase name="PreDispatch"/>
<phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
<handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher"/>
<handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher"/>
<handler name="RequestURIOperationDispatcher"
class="org.apache.axis2.dispatchers.RequestURIOperationDispatcher"/>
<handler name="SOAPMessageBodyBasedDispatcher"
class="org.apache.axis2.dispatchers.SOAPMessageBodyBasedDispatcher"/>
<handler name="HTTPLocationBasedDispatcher"
class="org.apache.axis2.dispatchers.HTTPLocationBasedDispatcher"/>
<handler name="GenericProviderDispatcher"
class="org.apache.axis2.jaxws.dispatchers.GenericProviderDispatcher"/>
<handler name="MustUnderstandValidationDispatcher"
class="org.apache.axis2.jaxws.dispatchers.MustUnderstandValidationDispatcher"/>
</phase>
<phase name="RMPhase"/>
<!-- user can add his own phases to this area -->
<phase name="OperationInFaultPhase"/>
<phase name="soapmonitorPhase"/>
</phaseOrder>
<phaseOrder type="OutFaultFlow">
<!-- user can add his own phases to this area -->
<phase name="soapmonitorPhase"/>
<phase name="OperationOutFaultPhase"/>
<phase name="RMPhase"/>
<phase name="PolicyDetermination"/>
<phase name="MessageOut"/>
<phase name="Security"/>
</phaseOrder>
</axisconfig>
In the java side, you need to create a custom axis2 configuration context, to use our custom axis2.xml. Axis2 offer multiple configurator, i prefer the file based one:
final ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem(
"c:\\work\\sources\\axis2conf",
"c:\\work\\sources\\axis2conf\\axis2.xml");
You can assign the configuration context to the client stub during the constructor:
FileNet_UploadDocumentWSStub stub = new FileNet_UploadDocumentWSStub(ctx, "https://testserver/test.asp");
So, if you doesn't want to use custom ssl settings, your upgrade is done.
Axis2 + Httpclient4 + SSL
After you upgraded to httpclient4, the implementation doesn't use the custom protocol handler property (HTTPConstants.CUSTOM_PROTOCOL_HANDLER) anymore.
The old implementation in org/apache/axis2/transport/http/impl/httpclient3/HTTPSenderImpl.java:524:
// one might need to set his own socket factory. Let's allow that case
// as well.
Protocol protocolHandler = (Protocol) msgCtx.getOptions().getProperty(
HTTPConstants.CUSTOM_PROTOCOL_HANDLER);
The new implementation org/apache/axis2/transport/http/impl/httpclient4/HTTPSenderImpl.java:583:
// TODO : one might need to set his own socket factory. We have to allow that case as well.
You need to setup ssl context in httpclient4 side. It's not a problem, because axis allow you to define httpclient for a ws call with HTTPConstants.CACHED_HTTP_CLIENT property:
options.setProperty(HTTPConstants.CACHED_HTTP_CLIENT, httpClient);
But if you create a httpclient4 for a standard way:
...
HttpClientBuilder builder = HttpClientBuilder.create();
...
and assign it to axis2 client stub, you got a ClassCastException, because all new httpclient Builder, factory, etc. methods create the "modern" implementation of httpclient, based on ClosableHttpClient. But axis2 implementation depends on deprecated AbstractHttpClient. So you need to create old version of httpclient.
The complete example:
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.Security;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.commons.httpclient.contrib.ssl.AuthSSLProtocolSocketFactory;
import org.apache.http.client.HttpClient;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.BasicClientConnectionManager;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.conn.SingleClientConnManager;
import org.apache.http.ssl.SSLContexts;
public class SslTest {
public SslTest() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) throws Exception {
File keyFile = new File("c:\\work\\sources\\ConsoleApp25\\avp-pc.jks");
final ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem(
"c:\\work\\sources\\axis2conf",
"c:\\work\\sources\\axis2conf\\axis2.xml");
FileNet_UploadocumentWSStub stub = new FileNet_UploadDocumentWSStub(ctx, "https://testserver/test.asp");
FileNet_UploadDocument wsMethodReq = new FileNet_UploadDocument();
ServiceClient serviceClient = stub._getServiceClient();
Options options = serviceClient.getOptions();
//keystore types: https://docs.oracle.com/javase/9/docs/specs/security/standard-names.html#keystore-types
KeyStore keyStore = KeyStore.getInstance("jks");
InputStream in = null;
try {
in = new FileInputStream(keyFile);
keyStore.load(in, "changeit".toCharArray());
} finally {
if (in != null) {
in.close();
}
}
//Factory instance types: https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#T5
//on IBM servers use IbmX509 instead of SunX509
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keyStore, "changeit".toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
trustManagerFactory.init(keyStore);
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
SSLSocketFactory sf = new SSLSocketFactory(sslContext);
Scheme httpsScheme = new Scheme("https", 443, sf);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(httpsScheme);
ClientConnectionManager cm = new SingleClientConnManager(schemeRegistry);
HttpClient httpClient = new DefaultHttpClient(cm);
options.setProperty(HTTPConstants.CACHED_HTTP_CLIENT, httpClient);
stub.fileNet_UploadDocument(wsMethodReq);
System.out.println("done");
}

Related

Apache camel http4 with self signed SSL certificate

I'm really stuck configuring Apache camel https4 for self signed server certificates that does not match the hostname.
[Do. 2020 16 Juli 13:13:19] [DEBUG] org.apache.camel.processor.Pipeline () - Message exchange has failed: so breaking out of pipeline for exchange: Exchange[ID-lvm-cdbservice-01ct-1594888044674-0-15551] Exception: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
That's why I created a custom HttpClientConfigurer as stated in the apache camel http configuration. But this configurer does not seem to be used for my route?! Does anybody know why?
The configureHttpClient method is used at some point
[Do. 2020 16 Juli 10:27:25] [INFO ] com.test.SelfSignedHttpClientConfigurer () - Using SelfSignedHttpClientConfigurer...
[Do. 2020 16 Juli 10:27:25] [INFO ] com.test.SelfSignedHttpClientConfigurer () - ... HttpClient configured!
But the protocols didn't change. That's why I guess it is not used for my route.
available protocols [[TLSv1.3, TLSv1.2, TLSv1.1, TLSv1]],
currently enabled protocols [[TLSv1.3, TLSv1.2, TLSv1.1, TLSv1]],
and default protocol patterns [Patterns [includes=[.*], excludes=[SSL.*]]].
Resulting enabled protocols are [[TLSv1.3, TLSv1.2, TLSv1.1, TLSv1]].
pom.xml
<properties>
<camel.version>2.24.3</camel.version>
</properties>
<dependencies>
<!-- camel -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-http4</artifactId>
<version>${camel.version}</version>
</dependency>
</dependencies>
applicationContext.xml
<!-- Apache Camel -->
<camelContext
xmlns="http://camel.apache.org/schema/spring">
<!-- HTTP myTime -->
<route id="myTimeRoute">
<from uri="file:///tmp/test?consumer.delay=10000" />
<setHeader headerName="CamelHttpMethod">
<constant>POST</constant>
</setHeader>
<setHeader headerName="Content-Type">
<constant>application/json</constant>
</setHeader>
<to uri="https4://test.de/test?delay=60000&connectTimeout=20000&httpClientConfigurer=#selfSignedHttpClientConfigurer&sslContextParameters=#mySSLContextParameters&throwExceptionOnFailure=false" />
</route>
</camelContext>
<bean id="selfSignedHttpClientConfigurer"
class="com.test.SelfSignedHttpClientConfigurer" />
I tried it with and without # (httpClientConfigurer=#selfSignedHttpClientConfigurer and httpClientConfigurer=selfSignedHttpClientConfigurer)
SelfSignedHttpClientConfigurer.class
package com.test;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import javax.net.ssl.SSLContext;
import org.apache.camel.component.http4.HttpClientConfigurer;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.ssl.SSLContexts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SelfSignedHttpClientConfigurer implements HttpClientConfigurer {
/** the logger. */
private static final Logger LOG = LoggerFactory.getLogger(SelfSignedHttpClientConfigurer.class);
#Override
public void configureHttpClient(HttpClientBuilder clientBuilder) {
try {
LOG.info("Using SelfSignedHttpClientConfigurer...");
SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();
// Allow TLSv1.2 protocol only
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1.2" },
null, NoopHostnameVerifier.INSTANCE);
clientBuilder.setSSLSocketFactory(sslsf);
LOG.info("... HttpClient configured!");
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
e.printStackTrace();
}
}
}
I tried with .build() and without.
I finally found a solution. All the tutorials and documentations are "deprecated", because the Apache HTTP API has changed with version 4.5. You will not get any errors in your code, but it is simply not working.
This post really helped me: https://stackoverflow.com/a/38509015
SelfSignedHttpClientConfigurer.class
package com.test;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import javax.net.ssl.SSLContext;
import org.apache.camel.component.http4.HttpClientConfigurer;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SelfSignedHttpClientConfigurer implements HttpClientConfigurer {
/** the logger. */
private static final Logger LOG = LoggerFactory.getLogger(SelfSignedHttpClientConfigurer.class);
#Override
public void configureHttpClient(HttpClientBuilder clientBuilder) {
try {
LOG.info("Using SelfSignedHttpClientConfigurer...");
final SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(null, (x509CertChain, authType) -> true).build();
clientBuilder.setSSLContext(sslContext)
.setConnectionManager(new PoolingHttpClientConnectionManager(RegistryBuilder
.<ConnectionSocketFactory> create().register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https",
new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE))
.build()));
LOG.info("... HttpClient configured!");
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
e.printStackTrace();
}
}
}
applicationContext.xml
<!-- Apache Camel -->
<camelContext
xmlns="http://camel.apache.org/schema/spring">
<!-- HTTP myTime -->
<route id="myTimeRoute">
<from uri="file:///tmp/test?consumer.delay=10000" />
<setHeader headerName="CamelHttpMethod">
<constant>POST</constant>
</setHeader>
<setHeader headerName="Content-Type">
<constant>application/json</constant>
</setHeader>
<to uri="https4://test.de/test?httpClientConfigurer=#selfSignedHttpClientConfigurer" />
</route>
</camelContext>
<bean id="selfSignedHttpClientConfigurer"
class="com.test.SelfSignedHttpClientConfigurer" />

ClassNotFoundException in reading Axis2 config file

I am trying to make a Web Service client connection using Axis2. To set UserameToken I must use PasswordCallBack.
Here is my client code:
ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem("src/main/resources/axis", "src/main/resources/axis/conf/axis2.xml");
TransactionProcessorStub stub = new TransactionProcessorStub(ctx, SERVER_URL);
ServiceClient client = stub._getServiceClient();
Options clientOptions = client.getOptions();
clientOptions.setProperty(WSHandlerConstants.USER, request.getMerchantID());
Here is my conf structure:
And within axis2.xml I set my Password Callback using samples from javaranch
Here is a snippet of code:
<phaseOrder type="InFlow">
<!-- System pre-defined phases -->
<phase name="Transport">
<handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.engine.RequestURIBasedDispatcher">
<order phase="Transport"/>
</handler>
<handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.engine.SOAPActionBasedDispatcher">
<order phase="Transport"/>
</handler>
</phase>
<phase name="Security"/>
<phase name="PreDispatch"/>
<phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
<handler name="AddressingBasedDispatcher"
class="org.apache.axis2.engine.AddressingBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="SOAPMessageBodyBasedDispatcher"
class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="InstanceDispatcher"
class="org.apache.axis2.engine.InstanceDispatcher">
<order phase="Dispatch"/>
</handler>
</phase>
<!-- System pre defined phases -->
<!-- After Postdispatch phase module author or or service author can add any phase he want -->
<phase name="OperationInPhase"/>
</phaseOrder>
I am using Maven to generate client code and and everything is going well with that.
The problem is when application tries to create ConfigurationContext in this line:
ConfigurationContextFactory.createConfigurationContextFromFileSystem("src/main/resources/axis",
"src/main/resources/axis/conf/axis2.xml");
I get ClassNotFoundException as below:
org.apache.axis2.deployment.DeploymentException:
org.apache.axis2.engine.RequestURIBasedDispatcher at
org.apache.axis2.deployment.util.Utils.loadHandler(Utils.java:147) at
org.apache.axis2.deployment.AxisConfigBuilder.processPhaseList(AxisConfigBuilder.java:575)
at
org.apache.axis2.deployment.AxisConfigBuilder.processPhaseOrders(AxisConfigBuilder.java:606)
at
org.apache.axis2.deployment.AxisConfigBuilder.populateConfig(AxisConfigBuilder.java:149)
at
org.apache.axis2.deployment.DeploymentEngine.populateAxisConfiguration(DeploymentEngine.java:629)
at
org.apache.axis2.deployment.FileSystemConfigurator.getAxisConfiguration(FileSystemConfigurator.java:116)
at
org.apache.axis2.context.ConfigurationContextFactory.createConfigurationContext(ConfigurationContextFactory.java:64)
at
org.apache.axis2.context.ConfigurationContextFactory.createConfigurationContextFromFileSystem(ConfigurationContextFactory.java:210)
at
au.com.jaycar.gateway.cybersourceClient.Sample.main(Sample.java:96)
Caused by: java.lang.ClassNotFoundException:
org.apache.axis2.engine.RequestURIBasedDispatcher at
java.net.URLClassLoader.findClass(URLClassLoader.java:381) at
java.lang.ClassLoader.loadClass(ClassLoader.java:424) at
sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) at
java.lang.ClassLoader.loadClass(ClassLoader.java:357) at
java.lang.Class.forName0(Native Method) at
java.lang.Class.forName(Class.java:264) at
org.apache.axis2.util.Loader.loadClass(Loader.java:261) at
org.apache.axis2.util.Loader.loadClass(Loader.java:229) at
org.apache.axis2.deployment.util.Utils.loadHandler(Utils.java:114)
... 8 more
I am not sure it is about missing library or configuration. Because I am sure it is in axis2-kernel which is in my maven dependencies, Otherwise source code wont be compiled.
Is there any issue with my configuration or classpath.
I could fix the issue. I didn't need to load axis2.xml and also server module. I removed both of them and I used policy.xml from the first sample code from rampart samples and load it into Client Options:
ConfigurationContext ctx =
ConfigurationContextFactory.createConfigurationContextFromFileSystem("src/main/resources/axis",
null); TransactionProcessorStub stub = new
TransactionProcessorStub(ctx, SERVER_URL); ServiceClient client =
stub._getServiceClient(); Options clientOptions = client.getOptions();
clientOptions.setProperty(WSHandlerConstants.USER,
request.getMerchantID()); StAXOMBuilder builder = new
StAXOMBuilder("src/main/resources/axis/conf/policy.xml"); Policy
policy = PolicyEngine.getPolicy(builder.getDocumentElement());
clientOptions.setProperty(RampartMessageData.KEY_RAMPART_POLICY,
policy); client.setOptions(clientOptions);
client.engageModule("rampart"); stub._setServiceClient(client);
ReplyMessageDocument response = stub.runTransaction(document);

How to enable encryption on a RMIIO stream using JBoss 6

I want to encrypt communications between a JBoss 6.1.0.Final server and my client. To do this I activated SSL over RMI and it works well. However, I use RMIIO too and it was not automatically encrypted when I activated SSL encryption over RMI. In a best case scenario, I would like to use the same encryption technique I used to encrypt RMI communications.
Here is my configuration:
server/myThing/deploy/remoting-jboss-beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="urn:jboss:bean-deployer:2.0">
<deployment xmlns="urn:jboss:bean-deployer:2.0">
<bean name="UnifiedInvokerConnector" class="org.jboss.remoting.transport.Connector">
<annotation>#org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss.remoting:service=Connector,transport=socket",exposedInterface=org.jboss.remoting.transport.ConnectorMBean.class,registerDirectly=true)</annotation>
<property name="serverConfiguration"><inject bean="UnifiedInvokerConfiguration"/></property>
<!-- add this to configure the SSL socket for the UnifiedInvoker -->
<property name="serverSocketFactory"><inject bean="SSLServerSocketFactoryEJB2"/></property>
</bean>
<!-- Remoting server configuration -->
<bean name="UnifiedInvokerConfiguration" class="org.jboss.remoting.ServerConfiguration">
<constructor>
<!-- Changed from socket to sslsocket -->
<parameter>sslsocket</parameter>
</constructor>
<!-- some other stuff, kept as the default config -->
</bean>
<!-- Some stuff removed to simplify the explanation -->
<!-- Added for SSL security -->
<bean name="SSLServerSocketFactoryEJB2" class="org.jboss.security.ssl.DomainServerSocketFactory">
<constructor>
<parameter><inject bean="EJB2SSLDomain"/></parameter>
</constructor>
</bean>
<!-- Added for SSL security -->
<bean name="EJB2SSLDomain" class="org.jboss.security.plugins.JaasSecurityDomain">
<constructor>
<parameter>EJB2SSLDomain</parameter>
</constructor>
<property name="keyStoreURL">C:\MyData\Security\ssl.keystore</property>
<property name="keyStorePass">MyPassword</property>
<property name="keyStoreAlias">MyAlias</property>
<property name="trustStorePass">MyPassword</property>
</bean>
</deployment>
server/myThing/deploy/properties-service.xml
<server>
<!-- some stuff removed -->
<mbean code="org.jboss.varia.property.SystemPropertiesService"
name="jboss:type=Service,name=SystemProperties">
<attribute name="Properties">
com.healthmarketscience.rmiio.exporter.port=11099
</attribute>
</mbean>
</server>
It's been awhile since i poked at RMI and SSL. However, RMIIO has a specific interface which allows you to customize the underlying "remoting" implementation, the RemoteStreamExporter. If you look at the DefaultRemoteStreamExporter implementation, you can see how the RMI objects are exported by default. My guess is that you want to use similar implementation which calls the 4 parameter export method with the appropriate RMI SSL socket factories.
Here is how I made it work, this was deduced from jtahlborn answer.
I got the JBoss config on RMI which is configured in remoting-jboss-beans.xml and initialise the SSLContext.setDefault with it. The code is called when JBoss is starting. Here is a simplified example of it.
KeyStore lKeyStore = KeyStore.getInstance( KeyStore.getDefaultType() );
InputStream lISKeyStore = new FileInputStream( new File( "C:/Security/ssl.keystore" ) );
try
{
lKeyStore.load( lISKeyStore, "MyPassword".toCharArray() );
}
finally
{
lISKeyStore.close();
}
KeyManagerFactory lKeyManagerFactory = KeyManagerFactory.getInstance( KeyManagerFactory.getDefaultAlgorithm() );
lKeyManagerFactory.init(lKeyStore, "MyPassword".toCharArray() );
KeyStore lTrustStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream lIStrustStore = new FileInputStream( new File( "C:/Security/ssl.truststore" ) );
try
{
lTrustStore.load(lIStrustStore, "MyPassword".toCharArray() );
}
finally
{
lIStrustStore.close();
}
TrustManagerFactory lTrustManagerFactory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm() );
lTrustManagerFactory.init(lTrustStore);
SSLContext lSSLContext = SSLContext.getInstance( "SSL" ); // Don't use SSLContext.getDefault() here it seems it's immutable.
lSSLContext.init( lKeyManagerFactory.getKeyManagers(), lTrustManagerFactory.getTrustManagers(), null );
SSLContext.setDefault( lSSLContext );
I also created my own RemoteStreamExporter
public class SSLRemoteStreamExporter extends DefaultRemoteStreamExporter
{
#Override
protected Object exportImpl(RemoteStreamServer<?,?> server)
throws RemoteException
{
// The SslRMIServerSocketFactory uses SSLContext.getDefault() to retrieve the configuration. The default must be initialized with right values.
return UnicastRemoteObject.exportObject(server, getPort(), new SslRMIClientSocketFactory(), new SslRMIServerSocketFactory() );
}
}
Afterward, I configured RMIIO to use my own RemoteStreamExporter
server/myThing/deploy/properties-service.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE server>
<!-- $Id: properties-service.xml 16662 2003-08-27 04:38:22Z patriot1burke $ -->
<server>
<!-- some stuff removed -->
<mbean code="org.jboss.varia.property.SystemPropertiesService"
name="jboss:type=Service,name=SystemProperties">
<attribute name="Properties">
com.healthmarketscience.rmiio.exporter.port=11099
com.healthmarketscience.rmiio.exporter=SSLRemoteStreamExporter
</attribute>
</mbean>
</server>

Spring data repository #Autowiring is null when using #Transactional annotation on service bean

I am studying spring framework and trying to use it in my project. But I have came across the following problem with spring data repository and #Transactional annotation used in my service. The problem is that there are no exceptions on the spring start up. Later on when I try to access spring data repository I get NullPointerException. Maybe you have some thoughts that could help me.
I am using spring data repository define as following:
package net.question.data.repository;
import net.question.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
Then I have a service defined which contains autowired repository:
package net.question.data.service;
import net.question.data.repository.UserRepository;
import net.question.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
#Service
#Transactional
public class UserService {
#Autowired
public UserRepository userRepository;
public void doStuff(User usr) {
// login will be here
}
}
here is the test to show my problem:
package net.question.spring;
import static org.junit.Assert.assertNotNull;
import net.question.data.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("/app-context.xml")
public class InjectionTestSuite {
#Autowired
UserService userService;
#Test
public void testRepositoryInjection() {
assertNotNull(userService);
assertNotNull(userService.userRepository);
}
}
The test fails on the follwowing line:
assertNotNull(userService.userRepository);
If I remove the #Transactional annotation on the service then the test passes.
here is my app-context.xml file:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd ">
<jpa:repositories base-package="net.question.data.repository" />
<!-- For discovering entity services -->
<context:component-scan base-package="net.question.data.service" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="hibernate_mysql" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven />
</beans>
Maybe you have some ideas, how to find the error?

How to limit Visibility of a popup menu only to a certain Project Type?

I am using menuContributions+popup to show a context menu in my plugin.xml. I need to limit it's visibility only to
certain type of Project(e.g. Dynamic Web Project) (Menu should appear on right click of only parent project folder) and
a particular folder(e.g Web Content) and it's sub folders inside the Project Folder structure.
I was able to achieve the 1) condition to some extent by using
<menuContribution locationURI="popup:common.new.menu?after=additions">
<command
label="Web Wiz"
commandId="commandId"
icon="icons/sample.gif">
<visibleWhen>
<with variable="selection">
<iterate ifEmpty="false"
operator="or">
<instanceof
value="org.eclipse.core.resources.IProject"/>
</iterate>
</with>
</visibleWhen>
</command>
</menuContribution>
but it appears for all kinds of projects...I need to limit it to only a Dynamic Web Project, so what should I add to meet this requirement in plugin.xml?
Add a propertyTester that will test your project type.
Use that tester in the visibleWhen
You can read about property-tester at the eclipse help, or at the extension help itself :)
EDIT - Check this one out as well - http://wiki.eclipse.org/Command_Core_Expressions#Property_Testers (especially the ResourcePropertyTester, which can provide you a built-in implementation that you can use)
For the second condition:
<test forcePluginActivation="true"
property="testWizard.propertyTester.checkFolder"
value="org.eclipse.wst.jsdt.core.jsNature"
</test>
is the reference to the property tester , which can be defined as
<extension
point="org.eclipse.core.expressions.propertyTesters">
<propertyTester
class="testwizard.wizards.MyPropTester"
id="MyPropTesterFolder"
namespace="testWizard.propertyTester"
properties="checkFolder"
type="org.eclipse.core.resources.IFolder">
</propertyTester>
then the kind of folder and it's subfolders can be tested as below in
package testwizard.wizards;
import org.eclipse.core.expressions.PropertyTester;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.runtime.CoreException;
public class MyPropTester extends PropertyTester{
#Override
public boolean test(Object receiver, String property, Object[] args,
Object expectedValue) {
IFolder folder=(IFolder)receiver;
String folderPath=folder.getProjectRelativePath().toString();
String arr[]=folderPath.split("/");
try {
if(folder.getProject().hasNature(expectedValue.toString()))
{
if(arr[0].equals("XYZ"))
{
return true;
}
}
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
}
<menuContribution locationURI="popup:common.new.menu?after=additions">
<command
label="Web Wiz"
commandId="commandId"
icon="icons/sample.gif">
<visibleWhen>
<with variable="selection">
<iterate operator="and" ifEmpty="false">
<test
property="org.eclipse.core.resources.projectNature"
value="your-project-nature" />
</iterate>
</with>
</visibleWhen>
</command>
<menuContribution>