Java RMI extremely slow when Server is not running - java

I have a GUI which uses RMI to get the data that has to be visualized. I'm doing server queries with an AnimationTimer, so in the worst case it could be 60 times/sec. When the server is running everything works perfectly.
However, if I run the client without the server beeing startet, the whole GUI gets really slow. It seems like the attempt to create a connection is the problem that blocks everything else. But I don't know how to solve it.
Another issue that I don't understand is following: When I close the server application via "x" in it's menubar there is still something running. I have to cancel the program a second time (in the Netbeans toolbar) to fully close it.
Following is the code which runs on client side. The getAllSignals()-method is invoked by an AnimationTimer:
public static RMI rmiConnect() {
try{
Registry reg = LocateRegistry.getRegistry("127.0.0.1", 1099);
RMI rmi = (RMI) reg.lookup("server");
return rmi;
} catch(RemoteException | NotBoundException e){
System.out.println(e);
return null;
}
}
public static Map<String, double> getAllSignals() throws RemoteException, IOException {
try {
RMI rmi = rmiConnect();
Map<String, double> signals = rmi.getAllSignals();
return (Map<String, double>) signals;
} catch (Exception ex) {
ExceptionsHandling exception = new ExceptionsHandling();
Map<String, double> list = exception.failedSignalsQuery();
return list;
}
}

Related

how to create a connection pool/only once for a third party Application?

I'm using JAVA/Spring MVC and I need to make a Connection Pool for a Third Party Application integration in my application becouse when i try to connect it multiple time my application and server System utilize 100% RAM.
here i have to problem, when users start to hit a specific method (callGenerationService()) multiple time, my Heap memory(RAM space) increases and becomes 100% and application going to slow becouse of it connect third party application multiple times ? here i need to create a connection only once and get it multiple times. where my connection like,
public class ClickToCallServiceImpl implements ClickToCallServiceInterface {
Client client = null;
#Override
public ClickToCall callGenerationService(ClickToCall clickToCall) {
client = new Client();
client.connect("127.0.0.1", 8021 , "password", 10); //Every time Connection Connect.
client.setEventSubscriptions("plain", "all");
// client.sendSyncApiCommand("",""); //here i run command on every hit like.
client.sendSyncApiCommand(clickToCall.command1, clickToCall.command2);
client.close();
}
}
and here 'ClickToCall' is a #Component Bean/POJO Class with variables setters and getters.
Is there, how to we create a connection (either pool or only once connect) for above connection where i connect only once and hit clickToCall.Command1 and clickToCall.Command2 multiple times and utilize less RAM? Thanks in advance.
Please note that I'm not an expert of freeswitch esl so you must check the code properly. Anyway this is what I would do.
First I create a Factory for Client
public class FreeSwitchEslClientFactory extends BasePooledObjectFactory<Client> {
#Override
public Client create() throws Exception {
//Create and connect: NOTE I'M NOT AN EXPERT OF ESL FREESWITCH SO YOU MUST CHECK IT PROPERLY
Client client = new Client();
client.connect("127.0.0.1", 8021 , "password", 10);
client.setEventSubscriptions("plain", "all");
return client;
}
#Override
public PooledObject<Client> wrap(Client obj) {
return new DefaultPooledObject<Client>(obj);
}
}
Then I create a shareable GenericObjectPool:
#Configuration
#ComponentScan(basePackages= {"it.olgna.spring.pool"})
public class CommonPoolConfig {
#Bean("clientPool")
public GenericObjectPool<Client> clientPool(){
GenericObjectPool<Client> result = new GenericObjectPool<Client>(new FreeSwitchEslClientFactory());
//Pool config e.g. max pool dimension
result.setMaxTotal(20);
return result;
}
}
Finally I use the created pool in order to get the Client obj:
#Component
public class FreeSwitchEslCommandSender {
#Autowired
#Qualifier("clientPool")
private GenericObjectPool<Client> pool;
public void sendCommand(String command, String param) throws Exception{
Client client = null;
try {
client = pool.borrowObject();
client.sendSyncApiCommand(command, param);
} finally {
if( client != null ) {
client.close();
}
pool.returnObject(client);
}
}
}
I didn't test (also because I can't) it but it should work. In any case I pray you to properly check the configuration. I don't know if it's OK to always create a Client object and connect or if it's better to connect when you want to send command
I hope it can be useful
EDIT INFORMATION
Sorry I made an error early. You must return the client to the pool
I updated my FreeSwitchEslCommandSender class
Angelo

Recovering from HBase server failure using Async HBase client

I'm currently trying to find a way to deal with unexpected HBase failures in my application. More specifically, what I'm trying to solve is a case where my application inserts data to HBase and then HBase fails and restarts.
In order to check how my application reacts to that scenario I wrote an application that uses HBase Async client by doing a tight loop and saving the results in HBase. When I start the application I can see rows are saved into the table, if during this time I intentionally fail my HBase server and restart it the client seems to reconnect but new insertions are not saved into the table
The code looks like this:
HConnection connection = HConnectionManager.createConnection();
HBaseClient hbaseClient = new HBaseClient(connection);
IntStream.range(0, 10000)
.forEach(new IntConsumer() {
#Override
public void accept(int value) {
try {
System.out.println("in value: " + value);
Thread.sleep(2000);
Get get = new Get(Bytes.toBytes("key"));
hbaseClient.get(TableName.valueOf("testTable"), get, new ResponseHandler<Result>() {
#Override
public void onSuccess(Result response) {
System.out.println("SUCCESS");
}
#Override
public void onFailure(IOException e) {
System.out.println("FAILURE");
}
});
urlsClient.save("valuekey", "w" + value, new FailureHandler<IOException>() {
#Override
public void onFailure(IOException failure) {
System.out.println("FAILURE");
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
This is obviously just a simple test but what I'm trying to achieve is that the async client will successfully save new rows after I restarted my HBase server. What the asynchronous HBase clients prints to me if I actually print the stacktrace in the "onFailure" method is:
org.apache.hadoop.hbase.ipc.RpcClient$CallTimeoutException: Call id=303, waitTime=60096, rpcTimeout=60000
at org.apache.hadoop.hbase.ipc.AsyncRpcChannel.cleanupCalls(AsyncRpcChannel.java:612)
at org.apache.hadoop.hbase.ipc.AsyncRpcChannel$1.run(AsyncRpcChannel.java:119)
at io.netty.util.HashedWheelTimer$HashedWheelTimeout.expire(HashedWheelTimer.java:581)
at io.netty.util.HashedWheelTimer$HashedWheelBucket.expireTimeouts(HashedWheelTimer.java:655)
at io.netty.util.HashedWheelTimer$Worker.run(HashedWheelTimer.java:367)
at java.lang.Thread.run(Thread.java:745)
And so my questions are:
How should one deal with a situation like I mentioned using the specified async client?
If this async client is no longer relevant could someone suggest a different async client that can perform asynchronous puts? I tried the BufferedMutator but it does not seem to actually flush any contents but just fails with the following java.lang.IllegalAccessError: tried to access method com.google.common.base.Stopwatch.<init>()V from class org.apache.hadoop.hbase.zookeeper.MetaTableLocator (but this gets a little off topic so I wont expand anymore)
Thanks
It's been quite a long time since I asked this question but I ended up using the HBase high availability instead of finding a way to solve it with code

How to set various parameters for Java RMI based communication?

While performing a client-server communication with various forums, I am unable to perform Remote-object's lookup on the client machine.
The errors which I receive are ConnectIOException(NoRouteToHostException), and sometimes ConnectException and sometimes someother.
This is not what I want to ask. But, the main concern is how should I setup client platform and server platform --- talking about networking details --- this is what I doubt interferes with my connection.
My questions :-
How should I edit my /etc/hosts file on both client-side and server-side? Server's IP- 192.168.1.8 & Client's IP-192.168.1.100. Means, should I add the system name in both the files:
192.168.1.8 SERVER-1 # on the server side
192.168.1.100 CLIENT-1 # on the client side
Should I edit like this? Can this be one of the possible concerns? I just want to remove any doubts left over to perform the rmi-communication!
Also, I am also setting Server's hostname property using System.setProperty("java.rmi.server.hostname",192.168.1.8); on the server side. Should I do the same on the client-side too?
I've read about setting classpath while running the java program on both server-side as well as the client-side. I did this too,but,again the same exceptions. No difference at all. I've read that since Java update 6u45, classpaths aren't necessary to include! Please throw some light on this too...
If I am missing something, Please enlighten about the same too. A brief idea/link to resources are most preferred.
You don't need any of this unless you have a problem. The most usual problem is the one described in the RMI FAQ #A.1, and editing the hosts file of the server or setting java.rmi.server.hostname in the server JVM is the solution to that.
'No route to host' is a network connectivity problem, not an RMI problem, and not one you'll solve with code or system property settings.
Setting the classpath has nothing to do with network problems.
Here is server example of which transfers an concrete class. This class must be exist in server and client classpath with same structure
Message:
public class MyMessage implements Serializable {
private static final long serialVersionUID = -696658756914311143L;
public String Title;
public String Body;
public MyMessage(String strTitle) {
Title = strTitle;
Body = "";
}
public MyMessage() {
Title = "";
Body = "";
}
}
And here is the server code that gets an message and returns another message:
public class SimpleServer {
public String ServerName;
ServerRemoteObject mRemoteObject;
public SimpleServer(String pServerName) {
ServerName = pServerName;
}
public void bindYourself() {
try {
mRemoteObject = new ServerRemoteObject(this);
java.rmi.registry.Registry iRegistry = LocateRegistry.getRegistry(RegistryContstants.RMIPort);
iRegistry.rebind(RegistryContstants.CMName, mRemoteObject);
} catch (Exception e) {
e.printStackTrace();
mRemoteObject = null;
}
}
public MyMessage handleEvent(MyMessage mMessage) {
MyMessage iMessage = new MyMessage();
iMessage.Body = "Response body";
iMessage.Title = "Response title";
return iMessage;
}
public static void main(String[] server) {
SimpleServer iServer = new SimpleServer("SERVER1");
iServer.bindYourself();
while (true) {
try {
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
and here is the remote interface of server remote object:
public interface ISimpleServer extends java.rmi.Remote{
public MyMessage doaction(MyMessage message) throws java.rmi.RemoteException;
}
all you need is adding MyMessage class both in server and client classpath.

Logging exceptions in Windows Service with WinRun4j

I have been trying to get a Windows service running from my JAR file. WinRun4j seems to be able to do the job, but I can't get it to work. I am especially finding it quite difficult to debug. I tried several methods for logging (writing to a .txt file, WinRun4j's EventLog class) but I can't seem to generate any output.
The service installs fine (eventually..) and I can start it. It should start a Jetty server that generates an XML file that can be reached over HTTP. The app works for a stand-alone version, just not for the service. The service is started, but as soon as I call the URL it stops without generating an error.
This is my Service class:
package com.some.package;
import org.boris.winrun4j.AbstractService;
import org.boris.winrun4j.ServiceException;
/**
* A basic service.
*/
public class StockService extends AbstractService {
private StockServer srv;
public int serviceMain(String[] args) throws ServiceException {
while (!shutdown) {
try {
Thread.sleep(5000);
} catch(InterruptedException e) {
}
if(srv == null) {
try {
srv = new StockServer();
srv.start();
} catch (Exception e) {
}
}
}
return 0;
}
}
I found out that the service didn't want to start if I started the Jetty server from the serviceMain class. I had to start a new thread. So StockServer extends Thread:
public class StockServer extends Thread {
private Server server;
public void run() {
if (server == null) {
try {
server = new Server(8080);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/example");
StockServlet stockServlet = new StockServlet();
context.addServlet(new ServletHolder(stockServlet), "/stock/*");
server.setHandler(context);
server.setStopAtShutdown(true);
server.start();
server.join();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}
Since it runs perfectly fine as Java application I just don't know how to get this thing debugged. I hope one of you can point me in the right direction :).
I ended up using the Java Service Wrapper (JSW). This seemed a lot more complex but ended up to be quite easy. It also provides logging by default so I could easily fix the errors. The JSW had problems finding the correct JDK, since JSW is 32bit and I installed JDK1.7 64 bit (and 1.6 32bit). Installing JDK1.7 32bit fixed it. That might have been the problem with WinRun4j as well, but that is something I will never know :).

java.rmi.NotBoundException

i have written small RMI chat program and its compiling properly.but when i try to run Client program it results exception "java.rmi.NotBoundException - ServerInterface"
Server program runs without any errors..please help me to solve this.
here is some of Client code
public static void main (String[] args)
{
String address = "rmi://localhost/ServerInterface";
try
{
ServerInterface si= (ServerInterface) Naming.lookup(address);
new Thread(new Client(si)).start();
}
catch (Exception e)
{
System.err.println(e.toString()) ;
}
}
It looks like you are attempting to look up a name that is not bound.
public class NotBoundException extends Exception
A NotBoundException
is thrown if an attempt is made to lookup or unbind in the registry a
name that has no associated binding.
A NotBoundException is thrown if an attempt is made to lookup or unbind in the registry a name that has no associated binding.
What is your server code look like? This exception you are having most likely caused by server not set up properly.
I think in your server code you are bind with name ChatServer
Naming.rebind("ChatServer", new Server());
But in your client code you are using ServerInterface name
String address = "rmi://localhost/ServerInterface";
For more details Naming
Just make sure your registry.rebind(ClassName.class.getSimpleName(), new ClassImplementaion()) is match to your ClassImplementation.

Categories

Resources