I am using SOAP call using cxf, and getting ssl readHandshakeRecord exception
unwinding now org.apache.cxf.interceptor.Fault: Could not send Message.
at
reason:
java.base/java.lang.Thread.run(Unknown Source)
Caused by: javax.net.ssl.SSLException: SSLException invoking https://myservice/Services: readHandshakeRecord
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at
.......
I also try to skip ssl validation with trust all certs
static {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
#Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
#Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
#Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
} };
SSLContext sc = null;
try {
sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
} catch (Exception e) {
log.error("Exception ssl ",e);
}
HostnameVerifier allHostsValid = new HostnameVerifier()
{
#Override
public boolean verify(String hostname, SSLSession session)
{
return true;
}
};
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
}
but still getting error
I also tries with TLSClientParameters
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(Hello.class);
factory.setAddress(address);
Hello portType = (Hello) factory.create();
try {
HostnameVerifier allHostsValid = new HostnameVerifier()
{
#Override
public boolean verify(String hostname, SSLSession session)
{
return true;
}
};
HTTPConduit httpCon = (HTTPConduit) ClientProxy.getClient(portType).getConduit();
TLSClientParameters parameters = new TLSClientParameters();
parameters.setSSLSocketFactory(sslSocketFactory);
parameters.setDisableCNCheck(true);
parameters.setHostnameVerifier(allHostsValid);
parameters.setTrustManagers(new TrustManager[] { new X509TrustManager() {
#Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws java.security.cert.CertificateException {
}
#Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws java.security.cert.CertificateException {
}
#Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}});
httpCon.setTlsClientParameters(parameters);
} catch (Exception e) {
System.out.ptintln( e);
}
but still getting same error
Need your valuable help
thank you in advance!
Related
I am having an issue with keystore, truststore, and LDAP credentials for Google.
I am using GraalVM 22.2 on JDK17 for the test.
I created a test class to be able to log into Google LDAP. Once, I figure out how to do it in the test, then I can move it into our application.
I downloaded my Google LDAP credential and key. I then followed the instructions from Google to create a KeyStore:
https://support.google.com/a/answer/9089736?hl=en#other-java-applications
According to Google's instructions, you just add the following to your System properties:
-Djavax.net.ssl.keyStore=[File Path to KeyStore] -Djavax.net.ssl.keyStorePassword=[KeyStore Pass]
-- OR --
System.setProperty("javax.net.ssl.keyStore", "[File Path to KeyStore]");
System.setProperty("javax.net.ssl.keyStorePassword", "[KeyStore Pass]");
The problem with this is we will have a KeyStore with a password that corresponds with a specific LDAP server. This is due to the fact that our application will be able to connect to multiple LDAP servers.
After doing some research, I saw you can create an SSLSocketFactory and set the property "java.naming.ldap.factory.socket". From there, you can add the KeyStore to use via the TrustManager, or KeyManager.
My problem is, when trying to connect to the Google LDAP server; the SSLSocketFactory is completely ignored. How do I know? None of the debugging statements in the SSLSocketFactory, TrustManger, or KeyManager are printed out. (I added a KeyStoreManager for debugging purposes.)
I even tried to import the keystore into cacerts with no luck. In fact, I had multiple problems importing because "keytool" kept complaining about the JKS vs PKCS12 format.
The only way I can connect successfully is to add the 2 System properties. I know I am missing something simple that will explain why it is not working correctly. Anyone got any ideas?
Here is my test class:
import java.io.Console;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.security.KeyStore;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.directory.InitialDirContext;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509TrustManager;
public class LDAPIT {
public static final String JAVA_NAMING_LDAP_FACTORY_SOCKET = "java.naming.ldap.factory.socket";
public static void main(final String[] args) {
final LDAPIT test = new LDAPIT();
try {
test.run();
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
public void run() throws Exception {
final Console cnsl = System.console();
if (cnsl == null) {
throw new RuntimeException("Console is null");
}
final String url = cnsl.readLine("Enter URL: ");
final String user = cnsl.readLine("Enter username : ");
final String password = String.valueOf(cnsl.readPassword("Enter password : "));
System.out.println("Start Trying to Connect to LDAP: " + url);
System.out.println("With User: " + user);
System.out.println("Creating LDAP Properties");
final Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
props.put(Context.PROVIDER_URL, url);
props.put(Context.SECURITY_PRINCIPAL, user);
props.put(Context.SECURITY_AUTHENTICATION, "simple");
props.put(Context.SECURITY_PROTOCOL, "ssl");
props.put(JAVA_NAMING_LDAP_FACTORY_SOCKET, MySSLSocketFactory.class.getName());
System.out.println("LDAP Properties without password: " + props);
props.put(Context.SECURITY_CREDENTIALS, password);
// System.setProperty("javax.net.ssl.keyStore", "[File Path to KeyStore]");
// System.setProperty("javax.net.ssl.keyStorePassword", "[KeyStore Pass]");
try {
System.out.println("Connecting to LDAP Server");
final InitialDirContext idc = new InitialDirContext(props);
System.out.println("Successfully connected to LDAP");
idc.close();
} catch (final Exception e) {
e.printStackTrace();
}
System.out.println("End Trying to Connect to LDAP");
}
public static class MySSLSocketFactory extends SSLSocketFactory {
private SSLSocketFactory socketFactory;
public MySSLSocketFactory() {
try {
System.out.println("Creating Key Manager");
final MyKeyManager keyManager = new MyKeyManager();
final KeyManager[] keyManagers = {keyManager};
System.out.println("Creating Trust Manager");
final MyTrustManager trustManager = new MyTrustManager();
final TrustManager[] trustManagers = {trustManager};
System.out.println("Creating Socket Context");
final SSLContext ctx = SSLContext.getInstance("TLS");
System.out.println("Initializing Socket Context");
ctx.init(keyManagers, trustManagers, new SecureRandom());
System.out.println("Creating Socket Factory");
socketFactory = ctx.getSocketFactory();
} catch (final Exception ex) {
ex.printStackTrace();
}
}
#Override
public String[] getDefaultCipherSuites() {
return socketFactory.getDefaultCipherSuites();
}
#Override
public String[] getSupportedCipherSuites() {
return socketFactory.getSupportedCipherSuites();
}
#Override
public Socket createSocket(Socket socket, String string, int i, boolean bln) throws IOException {
System.out.println("Creating Socket with: Socket, String, int, Boolean");
return socketFactory.createSocket(socket, string, i, bln);
}
#Override
public Socket createSocket(final Socket s, final InputStream consumed, final boolean autoClose) throws IOException {
System.out.println("Creating Socket with: Socket, InputStream, Boolean");
return super.createSocket(s, consumed, autoClose);
}
#Override
public Socket createSocket() throws IOException {
System.out.println("Creating Socket without parameters");
return super.createSocket();
}
#Override
public Socket createSocket(String string, int i) throws IOException {
System.out.println("Creating Socket with: String ,int");
return socketFactory.createSocket(string, i);
}
#Override
public Socket createSocket(String string, int i, InetAddress ia, int i1) throws IOException {
System.out.println("Creating Socket with: String, int, InetAddress, int");
return socketFactory.createSocket(string, i, ia, i1);
}
#Override
public Socket createSocket(InetAddress ia, int i) throws IOException {
System.out.println("Creating Socket with: InetAddress, int");
return socketFactory.createSocket(ia, i);
}
#Override
public Socket createSocket(InetAddress ia, int i, InetAddress ia1, int i1) throws IOException {
System.out.println("Creating Socket with: InetAddress, InetAddress, int");
return socketFactory.createSocket(ia, i, ia1, i1);
}
}
public static class MyKeyManager implements X509KeyManager {
#Override
public String[] getClientAliases(final String keyType, final Principal[] issuers) {
System.out.println("Getting Client Aliases: String, Principal[]");
return new String[0];
}
#Override
public String chooseClientAlias(final String[] keyType, final Principal[] issuers, final Socket socket) {
System.out.println("Choosing Client Alias: String[], Principal[], Socket");
return null;
}
#Override
public String[] getServerAliases(final String keyType, final Principal[] issuers) {
System.out.println("Getting Server Aliases: String, Principal[]");
return new String[0];
}
#Override
public String chooseServerAlias(final String keyType, final Principal[] issuers, final Socket socket) {
System.out.println("Choosing Server Aliases: String, Principal[], Socket");
return null;
}
#Override
public X509Certificate[] getCertificateChain(final String alias) {
System.out.println("Getting Certificate Chain: String");
return new X509Certificate[0];
}
#Override
public PrivateKey getPrivateKey(final String alias) {
System.out.println("Getting Private Key: String");
return null;
}
}
public static class MyTrustManager implements X509TrustManager {
private X509TrustManager gTrustManager;
public MyTrustManager() {
System.out.println("Creating My Trust Manager");
initTrustManager();
System.out.println("Created My Trust Manager");
}
#Override
public void checkClientTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {
if (gTrustManager != null) {
gTrustManager.checkClientTrusted(chain, authType);
}
}
#Override
public void checkServerTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {
if (gTrustManager != null) {
gTrustManager.checkServerTrusted(chain, authType);
}
}
#Override
public X509Certificate[] getAcceptedIssuers() {
return gTrustManager.getAcceptedIssuers();
}
private void initTrustManager() {
try {
final String keystoreType = KeyStore.getDefaultType();
System.out.println("Loading Keystore Type: " + keystoreType);
KeyStore keyStore = KeyStore.getInstance(keystoreType);
System.out.println("Loading CA Certs");
loadCACerts(keyStore);
System.out.println("Creating SSL Context");
System.out.println("Creating Trust Manager");
gTrustManager = getTrustManager(keyStore);
} catch (final Exception e) {
e.printStackTrace();
}
}
private void loadCACerts(final KeyStore keyStore) throws Exception {
final File keyStoreFile = new File("[File Path to KeyStore]]");
System.out.println("Loading Keystore: " + keyStoreFile.getAbsolutePath());
try (final FileInputStream keyStoreInputStream = new FileInputStream(keyStoreFile)) {
keyStore.load(keyStoreInputStream, "[KeyStore Pass]".toCharArray());
}
System.out.println("Keystore Loaded");
}
private X509TrustManager getTrustManager(final KeyStore k) throws Exception {
final String defaultAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
System.out.println("Loading Trust Manager Algorithm: " + defaultAlgorithm);
final TrustManagerFactory tmf = TrustManagerFactory.getInstance(defaultAlgorithm);
System.out.println("Initializing Trust Manager Factory");
tmf.init(k);
System.out.println("Getting Trust Managers");
final TrustManager[] tms = tmf.getTrustManagers();
int arraySize = 0;
if (tms != null) {
arraySize = tms.length;
}
System.out.println("Iterating through Trust Managers: " + arraySize);
for (final TrustManager tm : tms) {
System.out.println("Trust Manager: " + tm.getClass().getName());
if (tm instanceof final X509TrustManager x509TrustManager) {
System.out.println("Returning X509TrustManager");
return x509TrustManager;
}
}
System.out.println("Could not find correct Trust Manager, returning Null");
return null;
}
}
}
Wouldn't you know it...after I ask the question I figure it out. The answer was you MUST implement the 'getDefault()' method in your custom SSLSocketFactory. I knew it was something simple.
https://docs.oracle.com/javase/jndi/tutorial/ldap/security/ssl.html
Look at Using Custom Sockets.
Quite new with Dropwizard.
I found a lot of solution to deal with Jersey and ssl self signed certificate.
Dropwizard version is 0.9.2
I have tried to set a SSLContext but I get
The method sslContext(SSLContext) is undefined for the type JerseyClientBuilder
Code:
TrustManager[] certs = new TrustManager[]{
new X509TrustManager() {
#Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
#Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
#Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
}
};
public static class TrustAllHostNameVerifier implements HostnameVerifier {
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
private Client getWebClient(AppConfiguration configuration, Environment env) {
SSLContext ctx = SSLContext.getInstance("SSL");
ctx.init(null, certs, new SecureRandom());
Client client = new JerseyClientBuilder(env)
.using(configuration.getJerseyClient())
.sslContext(ctx)
.build("MyClient");
return client;
}
The configuration part:
private JerseyClientConfiguration jerseyClient = new JerseyClientConfiguration();
public JerseyClientConfiguration getJerseyClient() {
return jerseyClient;
}
I have found a simple solution just using the configuration
jerseyClient:
tls:
verifyHostname: false
trustSelfSignedCertificates: true
I think to create an insecure client in 0.9.2 you would use a Registry of ConnectionSocketFactory, something like...
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[] { new X509TrustManager() {
#Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
throws java.security.cert.CertificateException {
}
#Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
throws java.security.cert.CertificateException {
}
#Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
} }, new SecureRandom());
final SSLConnectionSocketFactory sslConnectionSocketFactory =
new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
final Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslConnectionSocketFactory)
.register("http", PlainConnectionSocketFactory.INSTANCE)
.build();
builder.using(registry);
Client client = new JerseyClientBuilder(env)
.using(configuration.getJerseyClient())
.using(registry)
.build("MyInsecureClient");
i'm using imap endpoint and i try to ignore SSL certificat by using:
the First class DummySSLSocketFactory :
public class DummySSLSocketFactory extends SSLSocketFactory {
private SSLSocketFactory factory;
public DummySSLSocketFactory() {
try {
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null,
new TrustManager[] { new
DummyTrustManager()},
null);
factory = (SSLSocketFactory)sslcontext.getSocketFactory();
} catch(Exception ex) {
// ignore
}
}
public static SocketFactory getDefault() {
return new DummySSLSocketFactory();
}
public Socket createSocket() throws IOException {
return factory.createSocket();
}
public Socket createSocket(Socket socket, String s, int i, boolean flag)
throws IOException {
return factory.createSocket(socket, s, i, flag);
}
public Socket createSocket(InetAddress inaddr, int i,
InetAddress inaddr1, int j) throws IOException {
return factory.createSocket(inaddr, i, inaddr1, j);
}
public Socket createSocket(InetAddress inaddr, int i)
throws IOException {
return factory.createSocket(inaddr, i);
}
public Socket createSocket(String s, int i, InetAddress inaddr, int j)
throws IOException {
return factory.createSocket(s, i, inaddr, j);
}
public Socket createSocket(String s, int i) throws IOException {
return factory.createSocket(s, i);
}
public String[] getDefaultCipherSuites() {
return factory.getDefaultCipherSuites();
}
public String[] getSupportedCipherSuites() {
return factory.getSupportedCipherSuites();
}
}
the second class DummyTrustManager :
public class DummyTrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] cert, String authType) {
// everything is trusted
}
public void checkServerTrusted(X509Certificate[] cert, String authType) {
// everything is trusted
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
the third class AllowAll to set java mail propeties:
public class AllowAll {
public void setsslproperties() {
//DummySSLSocketFactory easy = new EasySSLProtocolSocketFactory();
Properties props = System.getProperties();
props.setProperty("mail.imap.ssl.enable", "true");
props.setProperty("mail.imap.ssl.socketFactory.class","com.mycompany.imapssl.DummySSLSocketFactory");
props.setProperty("mail.imap.ssl.socketFactory.fallback", "false");
props.setProperty("mail.imap.socketFactory.port", "993");
Session session = Session.getInstance(props, null);
}
}
How can i associate this to the iMap EiP to ignore SSL Certificate ?
this is the route:
<route id="timerToLog">
<from uri="imaps://server:993?username=user_name&password=pass"/>
<log message="ok"/>
If you're using a recent version of JavaMail, set the mail.imap.ssl.trust property to the name of the host you want to trust. That avoids the need to create your own socket factory.
Ive been developing a rss reader which needs to make a mutal ssl authentication.
Ive managed to get the user certificate using the Keychain API and have got what seems to a mostly working SSLSocketFactory.
But whenever i try to make a connection to the server i get a 401 Unauthorized error, i feel its probably something to do with the way i am setting up my SSL Connection and my general code. If anyone can help point out what im doing wrong and what i need to do i would be greatly appreciative.
Main Activity:
public class AliasLoader extends AsyncTask<Void, Void, X509Certificate[]>
{
X509Certificate[] chain = null;
#Override protected X509Certificate[] doInBackground(Void... params) {
android.os.Debug.waitForDebugger();
if(!SavedAlias.isEmpty())
{
try {
PrivateKey key2 = KeyChain.getPrivateKey(getApplicationContext(), SavedAlias);
setPrivateKey(key2);
chain = KeyChain.getCertificateChain(getApplicationContext(),SavedAlias);
setCertificate(chain);
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
else
{
this.cancel(true);
}
return chain;
}
#Override
protected void onPostExecute(X509Certificate[] chain)
{
if(chain != null)
{
HttpClient client = CustomSSLSocketFactory.getNewHttpClient(context, getAlias(), chain, key);
String formDataServiceUrl = "https://android.diif.r.mil.uk";
WebView wv = (WebView) findViewById(R.id.rssFeedItemView);
HttpPost post = new HttpPost(formDataServiceUrl);
final HttpGet request = new HttpGet(formDataServiceUrl);
HttpResponse result = null;
try {
result = client.execute(post);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
wv.loadUrl(formDataServiceUrl);
}
else
{
Toast.makeText(getApplicationContext(), "Certificate is Empty", Toast.LENGTH_LONG).show();
}
}
}
CustomSSLSocketFactory:
public class CustomSSLSocketFactory extends SSLSocketFactory {
public static KeyStore rootCAtrustStore = null;
public static KeyStore clientKeyStore = null;
SSLContext sslContext = SSLContext.getInstance("TLS");
Context context;
/**
* Constructor.
*/
public CustomSSLSocketFactory(Context context, KeyStore keystore, String keyStorePassword, KeyStore truststore)
throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(keystore, keyStorePassword, truststore);
this.context = context;
// custom TrustManager,trusts all servers
X509TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
Log.i("CLIENT CERTIFICATES", "Loaded client certificates: " + keystore.size());
// initialize key manager factory with the client certificate
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keystore,null);
sslContext.init(keyManagerFactory.getKeyManagers(), new TrustManager[] { tm }, null);
//sslContext.init(null, new TrustManager[]{tm}, null);
}
#Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}
#Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
/**
* Create new HttpClient with CustomSSLSocketFactory.
*/
public static HttpClient getNewHttpClient(Context context, String alias, X509Certificate[] chain, PrivateKey key) {
try {
// This is method from tutorial ----------------------------------------------------
//The root CA Trust Store
rootCAtrustStore = KeyStore.getInstance("BKS");
rootCAtrustStore.load(null);
//InputStream in = context.getResources().openRawResource(com.DII.RSS_Viewer.R.raw.rootca);
//rootCAtrustStore.load(in, "PASSWORD".toCharArray());
//The Keystore with client certificates.
//clientKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
clientKeyStore = KeyStore.getInstance("pkcs12");
clientKeyStore.load(null);
// client certificate is stored in android's keystore
if((alias != null) && (chain != null))
{
Key pKey = key;
clientKeyStore.setKeyEntry(alias, pKey, "password".toCharArray(), chain);
}
//SSLSocketFactory sf = new CustomSSLSocketFactory(context, clientKeyStore, "password", rootCAtrustStore);
SSLSocketFactory sf = new SSLSocketFactory(clientKeyStore, "password");
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", (SocketFactory) sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return new DefaultHttpClient(ccm, params);
}
catch (Exception e)
{
return new DefaultHttpClient();
}
}
}
I am just trying to create a simple MINA server and client to evaluate. Here is my code.
public class Server {
private static final int PORT = 8080;
static class ServerHandler extends IoHandlerAdapter {
#Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
cause.printStackTrace();
}
#Override
public void sessionCreated(IoSession session) {
System.out.println("session is created");
session.write("Thank you");
}
#Override
public void sessionClosed(IoSession session) throws Exception {
System.out.println("session is closed.");
}
#Override
public void messageReceived(IoSession session, Object message) {
System.out.println("message=" + message);
session.write("Reply="+message);
}
}
/**
* #param args
*/
public static void main(String[] args) throws Exception {
SocketAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );
acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));
acceptor.setHandler(new Server.ServerHandler());
acceptor.getSessionConfig().setReadBufferSize( 2048 );
acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );
acceptor.bind(new InetSocketAddress(PORT));
System.out.println("Listening on port " + PORT);
for (;;) {
Thread.sleep(3000);
}
}
}
public class Client {
private static final int PORT = 8080;
private IoSession session;
private ClientHandler handler;
public Client() {
super();
}
public void initialize() throws Exception {
handler = new ClientHandler();
NioSocketConnector connector = new NioSocketConnector();
connector.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));
connector.getFilterChain().addLast("logger", new LoggingFilter());
connector.setHandler(handler);
for (;;) {
try {
ConnectFuture future = connector.connect(new InetSocketAddress(PORT));
future.awaitUninterruptibly();
session = future.getSession();
break;
} catch (RuntimeIoException e) {
System.err.println("Failed to connect.");
e.printStackTrace();
Thread.sleep(5000);
}
}
if (session == null) {
throw new Exception("Unable to get session");
}
Sender sender = new Sender();
sender.start();
session.getCloseFuture().awaitUninterruptibly();
connector.dispose();
System.out.println("client is done.");
}
/**
* #param args
*/
public static void main(String[] args) throws Exception {
Client client = new Client();
client.initialize();
}
class Sender extends Thread {
#Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.messageSent(session, "message");
}
}
class ClientHandler extends IoHandlerAdapter {
#Override
public void sessionOpened(IoSession session) {
}
#Override
public void messageSent(IoSession session, Object message) {
System.out.println("message sending=" + message);
session.write(message);
}
#Override
public void messageReceived(IoSession session, Object message) {
System.out.println("message receiving "+ message);
}
#Override
public void exceptionCaught(IoSession session, Throwable cause) {
cause.printStackTrace();
}
}
}
When I execute this code, the Client seems to keep sending a message instead of stopping after it sends. It looks to me that there is a recursive call in underlying MINA code. I know that I am doing something wrong.
Can somebody tell me how to fix this?
Thanks.
Try to initialize and start your sender and use the session within sessionOpened (ClientHandler)