I am currently setting up a small project using elastic search in Java, and I am trying to figure out how to gracefully handle the 'ConnectTransportException' when my ElasticSearchCluster is down.
private TransportClient buildClient() {
TransportClient client = null;
try {
client = new PreBuiltTransportClient(Settings.EMPTY)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));
} catch(UnknownHostException ex) {
logger.error("Unknown host {}: {}", "localhost", ex.getMessage());
}
return client;
}
This code works fine. When my ElasticSearch cluster isn't running I want to be able to know if the client was not able to connect to it and log an appropriate message and then handle it appropriately.
Currently when the client can't connect to the cluster I get this error:
org.elasticsearch.transport.ConnectTransportException: [][127.0.0.1:9300] connect_timeout[30s]
at org.elasticsearch.transport.netty4.Netty4Transport.connectToChannels(Netty4Transport.java:370) ~[transport-netty4-client-5.3.0.jar:5.3.0]
at org.elasticsearch.transport.TcpTransport.openConnection(TcpTransport.java:495) ~[elasticsearch-5.3.0.jar:5.3.0]
at org.elasticsearch.transport.TcpTransport.connectToNode(TcpTransport.java:460) ~[elasticsearch-5.3.0.jar:5.3.0]
at org.elasticsearch.transport.TransportService.connectToNode(TransportService.java:314) ~[elasticsearch-5.3.0.jar:5.3.0]
at org.elasticsearch.client.transport.TransportClientNodesService$SimpleNodeSampler.doSample(TransportClientNodesService.java:408) [elasticsearch-5.3.0.jar:5.3.0]
at org.elasticsearch.client.transport.TransportClientNodesService$NodeSampler.sample(TransportClientNodesService.java:354) [elasticsearch-5.3.0.jar:5.3.0]
at org.elasticsearch.client.transport.TransportClientNodesService.addTransportAddresses(TransportClientNodesService.java:195) [elasticsearch-5.3.0.jar:5.3.0]
at org.elasticsearch.client.transport.TransportClient.addTransportAddress(TransportClient.java:322) [elasticsearch-5.3.0.jar:5.3.0]
at elk.aggregator.ElasticClient.buildClient(ElasticClient.java:72) [classes/:?]
at elk.aggregator.ElasticClient.<init>(ElasticClient.java:62) [classes/:?]
at elk.aggregator.ElasticClient.getInstance(ElasticClient.java:55) [classes/:?]
at elk.aggregator.App.main(App.java:9) [classes/:?]
Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: localhost/127.0.0.1:9300
at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method) ~[?:1.8.0_111]
at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717) ~[?:1.8.0_111]
at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:346) ~[netty-transport-4.1.7.Final.jar:4.1.7.Final]
at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:340) ~[netty-transport-4.1.7.Final.jar:4.1.7.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:630) ~[netty-transport-4.1.7.Final.jar:4.1.7.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:527) ~[netty-transport-4.1.7.Final.jar:4.1.7.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:481) ~[netty-transport-4.1.7.Final.jar:4.1.7.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:441) ~[netty-transport-4.1.7.Final.jar:4.1.7.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) ~[netty-common-4.1.7.Final.jar:4.1.7.Final]
at java.lang.Thread.run(Thread.java:745) ~[?:1.8.0_111]
I want to be able to handle this gracefully by catching the error, but simply adding another catch block catching ConnectTransportException does not work.
Any idea how to do this?
You can seperate the code and handling for getting host and creating transport client then it will be more clear about the exception as below:
private boolean checkHostAvailability(String host, int port){
bool success = true;
try {
(new Socket(host, port)).close();
} catch (UnknownHostException e) {
success = false;
logger.error("Unknown host {}: {}", host, e.getMessage());
} catch (IOException e) {
success = false;
logger.error("Service not running host {}: {}, {}", host, port, e.getMessage());
}
retrun success;
}
private TransportClient buildClient() {
String host = "localhost";
int port = 9300;
if(checkHostAvailability(host,port){
TransportClient client = null;
try {
client = new PreBuiltTransportClient(Settings.EMPTY)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), port));
} catch(Exception ex) {
}
return client;
}
}
Related
Problem
I am trying to make a client in Java using gRPC. I have been given access to a kubernetes namespace to test out the client. However, all I have is the certificate authority for the cluster and a bearer token.
apiVersion: v1
clusters:
- cluster:
certificate-authority: /etc/ssl/certs/devwat-dal13-cruiser15-ca-bundle.pem
server: https://<host-ip>:<port>
name: devwat-dal13-cruiser15
contexts:
- context:
cluster: devwat-dal13-cruiser15
namespace: interns
user: devwat-dal13-cruiser15-sa-interns-editor
name: devwat-dal13-cruiser15-interns
current-context: devwat-dal13-cruiser15-interns
kind: Config
preferences: {}
users:
- name: devwat-dal13-cruiser15-sa-interns-editor
user:
token: <token>
Code
I don't know much about SSL and certificates but I tried to follow the documentation online on using SSL/TLS with gRPC with Java and came up with the following:
public class TrainerClient {
private ManagedChannel channel;
private TrainerGrpc.TrainerBlockingStub stub;
//private final String OVERRIDE_AUTHORITY = "24164dfe5c7842c98de431e53b6111d9-kubernetes-ca";
private final String CERT_FILE_PATH = Paths.get("/etc", "ssl", "certs", "devwat-dal13-cruiser15-ca-bundle.pem").toString();
private static final Logger logger = Logger.getLogger(TrainerClient.class.getName());
public TrainerClient(URL serviceUrl) {
File certFile = new File(CERT_FILE_PATH);
try {
logger.info("Initializing channel using SSL...");
this.channel = NettyChannelBuilder.forAddress(serviceUrl.getHost(), serviceUrl.getPort())
//.overrideAuthority(OVERRIDE_AUTHORITY)
.sslContext(getSslContext(certFile))
.build();
logger.info("Initializing new blocking stub...");
this.stub = TrainerGrpc.newBlockingStub(channel);
} catch (Exception ex) {
logger.log(Level.SEVERE, "Channel build failed: {0}", ex.toString());
System.exit(1);
}
}
public static void main(String[] args) {
TrainerClient client = null;
URL url = null;
String fullUrl = "http://localhost:8443";
try {
logger.info("Forming URL...");
url = new URL(fullUrl);
logger.info("Initializing client...");
client = new TrainerClient(url);
// Client Function Calls
TrainerOuterClass.GetAllRequest request = TrainerOuterClass.GetAllRequest.newBuilder().setUserId("").build();
TrainerOuterClass.GetAllResponse response = client.getAllTrainingsJobs(request);
} catch (Exception ex) {
if (ex instanceof MalformedURLException) {
logger.log(Level.SEVERE, "URL is malformed.");
} else {
logger.log(Level.SEVERE, "Exception has occurred: {0}", ex.getStackTrace());
ex.printStackTrace();
}
} finally {
if (client != null) {
try {
logger.info("Shutting down client...");
client.shutdown();
} catch (InterruptedException ex) {
logger.log(Level.WARNING, "Channel shutdown was interrupted.");
}
}
}
}
public SslContext getSslContext(File certFile) throws SSLException {
return GrpcSslContexts.forClient()
.trustManager(certFile)
.build();
}
private void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
}
The pod type is ClusterIP and is being port-forwarded to localhost with port 8443.
Error
When I run this, I get the following stack trace:
SEVERE: Exception has occurred:
io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:210)
io.grpc.StatusRuntimeException: UNAVAILABLE
at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:210)
at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:191)
at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:124)
at grpc.trainer.v2.TrainerGrpc$TrainerBlockingStub.getAllTrainingsJobs(TrainerGrpc.java:695)
at me.mikeygulati.grpc.TrainerClient.getAllTrainingsJobs(TrainerClient.java:70)
at me.mikeygulati.grpc.TrainerClient.main(TrainerClient.java:138)
Caused by: javax.net.ssl.SSLHandshakeException: General OpenSslEngine problem
at io.netty.handler.ssl.ReferenceCountedOpenSslContext$AbstractCertificateVerifier.verify(ReferenceCountedOpenSslContext.java:648)
at io.netty.internal.tcnative.SSL.readFromSSL(Native Method)
at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.readPlaintextData(ReferenceCountedOpenSslEngine.java:482)
at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.unwrap(ReferenceCountedOpenSslEngine.java:1020)
at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.unwrap(ReferenceCountedOpenSslEngine.java:1127)
at io.netty.handler.ssl.SslHandler$SslEngineType$1.unwrap(SslHandler.java:210)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1215)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1127)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1162)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1359)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:935)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.security.cert.CertificateException: No name matching localhost found
at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:231)
at sun.security.util.HostnameChecker.match(HostnameChecker.java:96)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:436)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:252)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:136)
at io.netty.handler.ssl.ReferenceCountedOpenSslClientContext$ExtendedTrustManagerVerifyCallback.verify(ReferenceCountedOpenSslClientContext.java:221)
at io.netty.handler.ssl.ReferenceCountedOpenSslContext$AbstractCertificateVerifier.verify(ReferenceCountedOpenSslContext.java:644)
... 26 more
Jul 24, 2018 10:52:05 AM me.mikeygulati.grpc.TrainerClient main
From what I have read online, this happens because the Common Name on the CA does not match the hostname, in my case, localhost. I have tried using an Override Authority so that it would match the Common Name in the CA but I got the same error.
So, I am fairly sure this is not the correct way to do it. I feel like I should have been supplied a client certificate and a client key with the kubernetes cluster but I didn't so, I want to ask if maybe there's something wrong with what I am doing.
Figured it out.
My company had a client certificate (client.crt) lying around that I was supposed to use instead of the CA. When I used that certificate instead with the proper override authority, the error went away.
I am getting "java.io.eof" exception,when i am trying to subscribe mqtt client. I am using eclipse paho library and using mosquitto broker. I am not getting any answer of this,so please help me why this happens ?
Mqtt connection and subscribe
I am using this code for connecting and subscribing to mosquitto
private void buildClient(String clientId){
log.debug("Connecting... "+clientId);
try {
mqttClient = new MqttClient(envConfiguration.getBrokerUrl(), clientId,new MemoryPersistence());
System.out.println(mqttClient.isConnected());
} catch (MqttException e) {
log.debug("build client stopped due to "+e.getCause());
}
chatCallback = new ChatCallback(this.userService,this);
mqttClient.setCallback(chatCallback);
mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setCleanSession(true);
}
#Override
public void connect(String clientId,String topic) {
try{
if(mqttClient == null || !mqttClient.getClientId().equals(clientId)){
buildClient(clientId);
mqttClient.connect(mqttConnectOptions);
subscribe(clientId,topic);
}
}catch (Exception e) {
log.debug("connection attempt failed "+ e.getCause() + " trying...");
}
}
#Override
public void subscribe(String clientId,String topic) throws MqttException {
if(mqttClient != null && mqttClient.isConnected()){
mqttClient.subscribe(topic,0);
/*try {
log.debug("Subscribing... with client id :: " + clientId + "topic");
mqttClient.subscribe(topic,2);
} catch (MqttException e) {
log.debug("subscribing error.."+e.getLocalizedMessage());
}*/
}
}
}
And mqtt call back
#Override
public void connectionLost(Throwable arg0) {
log.debug("Connection lost... attampting retrying due to "
+ arg0);
arg0.printStackTrace();
// chatServiceimpl.connect();
}
#Override
public void deliveryComplete(IMqttDeliveryToken arg0) {
log.debug("delivered message" + arg0);
// TODO Auto-generated method stub
}
#Override
public void messageArrived(String arg0, MqttMessage arg1) throws Exception {
log.debug("Message recived..." + arg1.toString());
userService.saveChat(arg1.toString());
}
I am facing this error when i am subscribing to mosquitto
Error logs
2015-11-30/18:19:00.877 [MQTT Call: 25287] DEBUG c.s.s.ChatCallback: Message recived...{ "id":"37153topic25287T1448886285.79573", "from":"37153", "to":"25287", "chatBody":[{"type": "text", "message":"The fact "}]}
2015-11-30/18:19:00.878 [MQTT Call: 25287] DEBUG c.s.s.u.UserService: Saving chat...
2015-11-30/18:19:00.883 [MQTT Call: 25287] DEBUG c.s.s.u.UserService: Get user by id::37153
2015-11-30/18:19:00.885 [MQTT Call: 25287] DEBUG c.s.s.u.UserService: Get user by id::25287
2015-11-30/18:19:00.886 [MQTT Rec: 25287] DEBUG c.s.s.ChatCallback: Connection lost... attampting retrying due to Connection lost (32109) - java.io.EOFException
Connection lost (32109) - java.io.EOFException
at org.eclipse.paho.client.mqttv3.internal.CommsReceiver.run(CommsReceiver.java:138)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.EOFException
at java.io.DataInputStream.readByte(DataInputStream.java:267)
at org.eclipse.paho.client.mqttv3.internal.wire.MqttInputStream.readMqttWireMessage(MqttInputStream.java:56)
at org.eclipse.paho.client.mqttv3.internal.CommsReceiver.run(CommsReceiver.java:100)
... 1 more
Mosquitto Logs
1448889230: Client 25287 disconnected.
1448889230: New client connected from 192.168.2.63 as 25287 (c0, k60).
1448889231: New connection from 192.168.2.242 on port 1883.
1448889231: Client 25287 already connected, closing old connection.
1448889231: Client 25287 disconnected.
1448889231: New client connected from 192.168.2.242 as 25287 (c1, k60).
1448889231: New connection from 192.168.2.63 on port 1883.
1448889231: Client 25287 already connected, closing old connection.
1448889231: Client 25287 disconnected.
1448889231: New client connected from 192.168.2.63 as 25287 (c0, k60).
1448889269: New connection from 192.168.2.242 on port 1883.
You have multiple clients connecting to the broker with the same clientid, this is not allowed and as one connects the broker will disconnect the currently connected client.
If both clients have automatic reconnection logic then they will just continue to kick each other off.
Change the client id on one of the clients.
As hardillb mentioned above, you have multiple clients connecting. Server (mosquitto) will disconnect the old connection when it receives a connect request from the same client again.
use the isConnected() method on MqttClient object to know if its connected. for eg.
if (! m_client.isConnected()) {
// reconnect
}
I finally managed to get SSL working between clients and my server... Atleast when running it directly from Netbeans.
Client network init code:
private Network(final String hostname, final int port) {
try {
URL resource = getClass().getResource("/truststore/TCGtruststore.jks");
if (resource == null) {
Controller.getInstance().write(MessageType.DEBUG, "Could not load trust store.");
throw new IllegalStateException("network.Network: Could not load trust store.");
}
else {
Controller.getInstance().write(MessageType.LOG, "Loaded trust store.");
}
System.setProperty("javax.net.ssl.trustStore", resource.getPath());
System.setProperty("javax.net.ssl.trustStorePassword", "tcgadmin");
Socket baseSocket = new Socket();
baseSocket.connect(new InetSocketAddress(hostname, port), Config.TIMEOUT);
SSLSocketFactory socketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
clientSocket = (SSLSocket)socketFactory.createSocket(baseSocket, hostname, port, true);
clientSocket.startHandshake();
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
connected = true;
} catch (IOException ex) {
connected = false;
}
waitForServer = new HashMap<>();
}
Server network init code:
public Server(final int port) {
this.port = port;
try {
URL resource = getClass().getResource("/keystore/TCGkeystore.jks");
if (resource == null) {
throw new IllegalStateException("server.Server: Could not load key store.");
}
System.setProperty("javax.net.ssl.keyStore", resource.getPath());
System.setProperty("javax.net.ssl.keyStorePassword", "tcgadmin");
//serverSocket = new ServerSocket(port);
serverSocket = (SSLServerSocket)SSLServerSocketFactory.getDefault().createServerSocket(port);
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
However when I clean and build it, and run it outside Netbeans, it breaks.
Surprisingly enough the client still behaves fine though, it is the server that starts acting strange with this message:
mei 20, 2013 4:36:16 PM server.ServerConnectionReceiver run
SEVERE: null
javax.net.ssl.SSLException: Received fatal alert: internal_error
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1977)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1093)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1328)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:882)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:102)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:154)
at java.io.BufferedReader.readLine(BufferedReader.java:317)
at java.io.BufferedReader.readLine(BufferedReader.java:382)
at server.ServerConnectionReceiver.run(ServerConnectionReceiver.java:45)
at java.lang.Thread.run(Thread.java:722)
Command line code from client:
[16:36:15] [Log] Loaded trust store.
[16:36:16] [Log] Could not establish a connection with the server.
Does anyone have any clue on what went wrong?
When server runs from within netbeans and client aswell, everything is fine.
When server runs from within netbeans and client via commandline, the server gives an exception.
When I try to run the server from commandline, it gives an error. (I was about to test if it would work with both from commandline, but I unfortunately cannot just test that)
Regards.
I am running in to some trouble when shutting down the server component and was hoping to get some help.
My server code looks as follows, it has a method to shut down the server
Server
private final String address = "127.0.0.1";
private Registry registry;
private int port = 6789;
public RmiServer() throws RemoteException {
try {
registry = LocateRegistry.createRegistry(port);
registry.rebind("rmiServer", this);
} catch (RemoteException e) {
logger.error("Unable to start the server. Exiting the application.", e);
System.exit(-1);
}
}
public void shutDownServer() throws RemoteException {
int succesful = 0;
try {
registry.unbind("rmiServer");
UnicastRemoteObject.unexportObject(this, true);
Thread.sleep(1000);
} catch (NotBoundException e) {
logger.error("Error shutting down the server - could not unbind the registry", e);
succesful = -1;
} catch (InterruptedException e) {
logger.info("Unable to sleep when shutting down the server", e);
succesful = -1;
}
catch (AccessException e) {
logger.info("Access Exception", e);
succesful = -1;
}
catch (UnmarshalException e) {
System.out.println(e.detail.getMessage());
logger.info("UnMarshall Exception", e);
succesful = -1;
}
catch (RemoteException e) {
System.out.println(e.detail.getMessage());
logger.info("Remote Exception", e);
succesful = -1;
}
logger.info("server shut down gracefully");
System.exit(succesful);
}
My client connects fine, no issues, so to shutdown i created a new application, copied the client code to connect and then call the close method on the server
Shutdown
public class Shutdown {
private String serverAddress = "127.0.0.1";
private String serverPort = "6789";
private ReceiveMessageInterface rmiServer;
private Registry registry;
public Shutdown(){
try {
registry = LocateRegistry.getRegistry(serverAddress, (new Integer(serverPort)).intValue());
rmiServer = (ReceiveMessageInterface) (registry.lookup("rmiServer"));
logger.info("Client started correctly");
rmiServer.shutDownServer();
System.exit(0);
}
catch (UnmarshalException e ){
logger.error("Unmarshall exception. Exiting application", e);
System.exit(-1);
}
catch (RemoteException e) {
logger.error("Remote object exception occured when connecting to server. Exiting application", e);
System.exit(-1);
} catch (NotBoundException e) {
logger.error("Not Bound Exception occured when connecting to server. Exiting application", e);
System.exit(-1);
}
}
No matter what i try i keep getting the following exception;
ERROR com.rmi.client.RMIClient - Unmarshall exception. Exiting application
java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is:
java.net.SocketException: Connection reset
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at $Proxy0.shutDownServer(Unknown Source)
at com.rmi.shutdown.Shutdown.<init>(Shutdown.java:31)
at com.rmi.shutdown.Shutdown.main(Shutdown.java:52)
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at java.io.DataInputStream.readByte(Unknown Source)
... 7 more
I belive this might be due to the fact that the client is not properly disconnected and just gets "cut off" but i am unsure how else to disconnect the server side?
please can some one advise.
thanks
Unexport with force = true doesn't abort calls in progress. In general it will let in-progress calls run to completion. Your shutDownServer method is almost correct in that it unregisters the remote reference and unexports it. What it does next doesn't work, though. First, it sleeps for one second. This keeps the call in progress and keeps the client waiting for a reply. Then the shutdown code exits the server JVM without returning from the remote call. This closes client's connection while it's still awaiting a reply. That's why the client gets the connection reset exception.
To shut down cleanly, unregister the remote object, unexport it with force = true (as you've done) and then simply return. This will send a reply to the client, letting its remote call complete, and it will then exit. Back on the server, after the last in-progress call has completed, if there are no other objects exported, and if there's nothing else keeping the JVM around (such as non-daemon threads) the JVM will exit. You need to let RMI finish up its server-side processing instead of calling System.exit().
The system is doing exactly what you told it to do. You told it to unexport itself, and you set the 'force' parameter to true, which aborts calls in progress, so it unexported itself and aborted the call in progress. Just ignore it, or if you insist on a clean response to the shutdown client, have the server start a new thread for the unexport operation, with a short delay so the shutdown call can return to the client.
I'm making a vysper xmpp server.
Here's my code:
public static void main(String[] args) throws Exception {
XMPPServer server = new XMPPServer("myserver.org");
StorageProviderRegistry providerRegistry = new MemoryStorageProviderRegistry();
AccountManagement accountManagement = (AccountManagement) providerRegistry.retrieve(AccountManagement.class);
Entity user = EntityImpl.parseUnchecked("user#myserver.org");
accountManagement.addUser(user, "password");
server.setStorageProviderRegistry(providerRegistry);
server.addEndpoint(new TCPEndpoint())
server.setTLSCertificateInfo(new File("keystore.jks"), "boguspw");
//server.setTLSCertificateInfo(new File("bogus_mina_tls.cert"), "boguspw");
server.start();
System.out.println("Vysper server is running...");
server.addModule(new EntityTimeModule());
server.addModule(new VcardTempModule());
server.addModule(new XmppPingModule());
server.addModule(new PrivateDataModule());
}
I've tried both certificate files. (keystore.jks,bogus_mina_tls.cert)
After I start the server, it connects to it, and tries to login but it can't login.
SmackConfiguration.setPacketReplyTimeout(5000);
config = new ConnectionConfiguration("myserver.org", port, "localhost");
config.setSelfSignedCertificateEnabled(true);
config.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled);
config.setSASLAuthenticationEnabled(true);
// config.setKeystorePath("keystore.jks");
// config.setTruststorePath("keystore.jks");
config.setKeystorePath("bogus_mina_tls.cert");
config.setTruststorePath("bogus_mina_tls.cert");
config.setTruststorePassword("boguspw");
XMPPConnection.DEBUG_ENABLED = true;
connection = new XMPPConnection(config);
try {
connection.connect();
} catch (XMPPException e) {
System.out.println("Error connect");
e.printStackTrace();
}
System.out.println("Connected: " + connection.isConnected());
try {
System.out.println(connection.isAuthenticated());
connection.login("user", "password");
} catch (XMPPException e) {
System.out.println("Error login");
e.printStackTrace();
}
I catch this exception:
SASL authentication PLAIN failed: incorrect-encoding: at
org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:337)
at
org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:203)
at org.jivesoftware.smack.Connection.login(Connection.java:348) at
com.protocol7.vysper.intro.WorkingClient.init(WorkingClient.java:57)
at
com.protocol7.vysper.intro.WorkingClient.(WorkingClient.java:27)
at com.protocol7.vysper.intro.Runclient.main(Runclient.java:11)
I've seen these examples (1st, 2nd) but they don't work.
At first please note that the server certificate is not used for user authentication, it is used to provide secure communication channel between client and server.
From the log you can see that your authentication method is "SASL PLAIN", using a user and password.
On the server, you are setting username/password as:
accountManagement.addUser("user#myserver.org", "password");
but on the client you're using
connection.login("user", "password");
This doesn't fit with the error message you are posting, but I'd suggest you try again with correct user/password.