java.rmi.UnmarshalException: unable to pull client classes by server - java

I have an RMI client/server set-up on two machines that works fine in a simple situation when the server doesn't require a client-side defned class. However, when I need to use a class defined on the client side I am unable to have the server unmarshall those classes. I suspect this is an issue with my java.rmi.server.codebase property that I pass in as argument to the client app. I followed Sun's RMI Tutorial trail and I think I have followed the steps exactly except that I don't specify a classpath argument when executing client and server because they execute in the directory right above the root package directory (however I tried that too with no effect).
The exceptions I get when attempting to execute the different client-side combinations described in detail below are all the same:
RmiServer exception:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: test.MyTask
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:353)
at sun.rmi.transport.Transport$1.run(Transport.java:177)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:636)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:178)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:132)
at $Proxy0.execute(Unknown Source)
at test.myClient.main(myClient.java:32)
The details are:
My client/server rmi is set up over a home network behind a router. The router is assigned to a static ip address I will call myhostname. Appropriate port-mapping is set-up in the router that points to the right machines.
role, machine, os, ip-address:
server, venice, linux ubuntu 9.10, 10.0.1.2
client, naples, mac os x leopard, 10.0.1.4
I startup the server side as follows inside /home/andrews/workspace/epsilon/bin:
1 starting registry on the default port 1099:
venice% rmiregistry &
2 starting web-server on port 2001 pointing to code base for common interfaces:
venice% java webserver/ClassFileServer 2001 /home/andrew/workspace/epsilon/bin
3 starting server app (main class in test/myServer) which registers the server object:
venice% java -Djava.rmi.server.codebase="http://myhostname:2001/" -Djava.security.policy=server.policy -Djava.rmi.server.hostname=myhostname test/myServer &
Now the client side inside /Users/andrews/Development/Java/workspace/epsilon/bin:
1 start a local web server that can server client-side classes to the server (not sure if this is needed, but I added I tried it, and still no success; I have added port-mapping to the router for 2001 to venice, for 2002 to naples)
naples$ java webserver/ClassFileServer 2002 /Users/andrews/Development/Java/workspace/epsilon/bin/
Trying to run the client (note: I don't specify the -cp argument because client executes right above the root package directory):
1 try #1 using an http hostname
naples$ java -Djava.rmi.server.codebase=http://10.0.1.4:2002/ -Djava.security.policy=client.policy test.myClient myhostname
Note 1: the myhostname argument at the end is passed-in to the client so that it resolves to server's rmi hostname.
Note 2: I tried using localhost:2002 instead of 10.0.1.4:2002 too.
Note 3: I tried using myhostname:2002 since myhostname is assigned to the router and I have proper port-mapping set-up, this address should resolve to naples and not venice
2 try #2:
naples$ java -Djava.rmi.server.codebase=file:/Users/andrews/Development/Java/workspace/epsilon/bin/ -Djava.security.policy=client.policy test.myClient myhostname
Note 1: the code base url format is correct, I created a small program to convert current file directory path into a url and used that. using file:///Users... has same effect.
Other notes:
1 my server and client policy files correctly specify the path, as I've tested this setup with good and bad paths, and getting a security exception for bad path
2 this setup works if I don't use client-side defined objects, the client connects correctly to the server and the server executes.
3 when I place the client-side class on the server in the server's classpath, all executes fine.
All help is appreciated.

Do you really need to use RMI? Me and a friend tried it once in school and it was way slow, much slower then the simple ObjectOutputStream networking we had been doing earlier.

I strong agree with Chad Okere's said, RMI is really very slow and consuming-resouces. sometimes directly use Sockets maybe is simple and useful chooice, regarding your exception Could you confirm your rmi server work correctly? http://www.javarmi.com/2010/05/java-rmi-error-unmarshalling-arguments/ maybe be can help you

Related

How to connect to a Grakn Server running on a GCP VM instance

I'm trying to connect to a Grakn Server running on a GCP VM instance. I have read the related post in the discussion forum. One of the replies suggests to do the following on the server side:
Edit ./conf/main/grakn.properties:
storage.hostname=EXTERNAL.ip.v4.address
Edit ./conf/cassandra/cassandra.yaml:
seeds: "EXTERNAL.ip.v4.address"
broadcast_address: EXTERNAL.ip.v4.address
listen_address: INTERNAL.ip.v4.address
rpc_address: INTERNAL.ip.v4.address
Access it from the Java API:
GraknSession session = Grakn.session(“EXTERNAL.ip.v4.address”, keySpaceName);
What i have interpreted from this, for my specific case, is the following:
-Replace EXTERNAL.ip.v4.address with the External IP of my VM instance
-Replace INTERNAL.ip.v4.address with the Internal IP of my VM instance
When i start the server i get this exception cause (I think this is the root cause):
Caused by:
com.netflix.astyanax.connectionpool.exceptions.PoolTimeoutException:
PoolTimeoutException: [host=104.197.131.17(104.197.131.17):9160,
latency=10000(10000), attempts=1]Timed out waiting for connection
at com.netflix.astyanax.connectionpool.impl.SimpleHostConnectionPool.waitForConnection(SimpleHostConnectionPool.java:231)
What am i missing?
Do i have to add firewall rules?
Thanks for the help.
To access Grakn remotely using the Java API, you need to open the following ports on the GCP and Linux VM firewall (eg. iptables):
4567
9160
Make sure you are able to access those from the client machine.

Java RMI registry can't find server object

So, the problem is I have some server code that will allow a Client to call functions on it using rmiregistry. It should be noted I'm running these commands on OS X terminal and I have two folders I'm working within:
RMI - which will call the rmiregistry and
Server - which has all my server code in it
So, I open one terminal and enter this:
rmiregistry -J-Djava.rmi.server.codebase=file:/Desktop/RMI/Server/ &
All is well, I get a port back.
I then login to the Server folder that contains my server code to run my calculatorserver program.
Now I've been told to specify the codebase and the security policy:
java -Djava.rmi.server.codebase=file:/Desktop/RMI/Server/ -Djava.security.policy=server.policy calculatorserver
However, I keep on getting this same error:
Server Error: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: calculator
I know the only reason I'm getting this error is because the rmiregistry can't find the server object.
Some guidance would be appreciated
That's not a real HTTP URL. It's a directory name with http: stuck in front of it. You need to use a real http: URL with a real HTTP server. Or FTP.
You can use a file: URL, but then you're more or less stuck within a single host, in which case you don't actually need the codebase feature at all. And if you do use a file: URL, it has to be intelligible to the Registry and the client, which again means either they're all in the same host or it names a shared directory that the Registry and client can see.
NB Don't specify the codebase to the Registry (or the client, unless it exports remote (callback) objects): only to the server JVM

UnknownHostException from Java but host resolves with Ping/nslookup/curl

We are getting the following exception when a Java EE server tries to resolve a host name from one of the services. We were able to resolve that host name on the box manually with ping/nslookup command. We were also able to fire that external service using curl with same parameters what server is trying to use. So it seems like this issue happens only when we try to make a request to a external host from a Java/Java EE application.
To resolve this issue, we manually added an entry in /etc/hosts file and it solved the problem but we want a permanent solution so we don't have to keep changing the IP. It was working before without adding that entry but all of a sudden it stopped working.
Detail of our environment:
OS: Cent OS 6.3
Java : JDK 1.6.0_24
Java EE Server : JBoss AS 7.1.1
Http Client library : httpclient-4.0.jar
Thanks in advance for the help!!
Error while checking salesforce license|:
java.net.UnknownHostException: na15.salesforce.com at
java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:175)
[rt.jar:1.6.0_24] at
java.net.SocksSocketImpl.connect(SocksSocketImpl.java:384)
[rt.jar:1.6.0_24] at java.net.Socket.connect(Socket.java:546)
[rt.jar:1.6.0_24] at
sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:584)
[jsse.jar:1.6.0_24] at
org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:333)
[httpclient-4.0.jar:4.0] at
org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:123)
[httpclient-4.0.jar:4.0] at
org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:147)
[httpclient-4.0.jar:4.0] at
org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:101)
[httpclient-4.0.jar:4.0] at
org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:381)
[httpclient-4.0.jar:4.0] at
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
[httpclient-4.0.jar:4.0] at
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
[httpclient-4.0.jar:4.0]
This is most likely a network management, change / configuration management or general system administration problem rather than a programming problem.
It was working before without adding that entry but all of a sudden it stopped working.
One approach is to try to figure out what changed to cause it to stop working. This is not the kind of thing that would happen spontaneously. Someone or something has changed some software or configurations to make this happen. Start with when it stopped (or when you noticed) and work back through your change logs.
It sounds like it is an issue with the Java DNS resolution procedure. It appears that the resolver is either not trying to talk to the normal DNS servers, or it is trying and failing.
We can't debug it for you, but I found these resources that help to explain what should be happening when you do a name lookup in Java, and offer some ideas on trouble-shooting.
Resources:
DNS and Java
Java doesn't pick up system's DNS settings change until restarted
Java and /etc/resolv.conf DNS server failover
Java networking properties
I found that these same symptoms can happen when IPv6 is disabled on your networking. You can see this by running a simple Java program:
import java.net.InetAddress;
public class NameTest
{
public static void main(String[] args) throws Exception
{
System.out.println(InetAddress.getByName("google.com"));
}
}
If IPv6 is an issue, then running the program with java -cp . NameTest will fail with a line like "at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)" in the stack trace (notice the Inet6 in the class name), and running the program with java -cp . -Djava.net.preferIPv4Stack=true NameTest will succeed (this is from the above answer Java networking properties reference).
To work past this, I followed suggestions from this question.
An OS-wide disabling of IPv6 works well, as the system doesn't have IPv6. On some Linux varieties, this can be disabled by first adding this line to the end of the file /etc/sysctl.conf
net.ipv6.conf.all.disable_ipv6 = 1
followed by running sudo sysctl -p to immediately disable IPv6.

Why does java rmi keep connecting to 127.0.1.1. When ip is 192.168.X.X?

I have a java rmi application i simply do:
Client:
Registry registry = LocateRegistry.getRegistry("localhost");
costApi = (CostApi) registry.lookup("server.CostApi");
Everything works fine when I host the server at localhost. When I start the same program at another machine withing the local network, at 192.168.x.x and change to:
Client:
Registry registry = LocateRegistry.getRegistry("192.168.x.x");
costApi = (CostApi) registry.lookup("server.CostApi");
it does not work anymore and it fails with a very strange error:
java.rmi.ConnectException: Connection refused to host: 127.0.1.1; nested exception is:
java.net.ConnectException: Connection refused
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:129)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
at com.sun.proxy.$Proxy0.dataCost(Unknown Source)
at billing.data.DataBiller.performBilling(DataBiller.java:57)
at billing.data.DataBiller.consumeMessage(DataBiller.java:46)
at general.templates.RabbitWorker.run(RabbitWorker.java:124)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
I'm not even trying to connect to 127.0.1.1 but to 192.168.x.x, how do I solve this? I prefer to use java code only and not modify my machine with config files. I'm using linux
This is usually caused by a misconfiguration. Check your /etc/hosts file to ensure that:
localhost maps to 127.0.0.1
your real hostname maps to your real host address
Some Linux distributions are known to have this back to front.
If the problem persists, try setting java.rmi.server.hostname at the server to the IP address the client should use when executing remote method calls. It needs to be set before you export any remote objects, including the Registry.
The problem is caused by the IP address embedded in the stub, which ultimately comes from something like InetAddress.getLocalAddress(), which is fallible as above. It is overridden by java.rmi.server.hostname.
This is item A.1 in the FMI FAQ, but note that the item is mistitled. It doesn't happen during lookup(), it happens when you call a remote method on the resulting stub.
I just ran into the same issue. I'm doing something very similar to what you are doing. What I noticed was that the first time I ran the client program, and it failed ( by design of the firewall test ) - that it failed with an error message showing the actual ip address of the host that I originally specified ( the 192.168.x.x address ), but all subsequent failures show that it is failing to make a connection to 127.0.0.1. Currently I'm suspecting some kind of caching on the client - has the JVM marked that ip address as never accessible again and it's refusing to ever try to connect to it again?
UPDATE: In my case, the JVM on the RMI Server side was not able to properly set the java.rmi.server.hostname property at JVM startup. This property was being left as null. When clients connect to a specific RMI Registry and ask for a stub to a particular named object, they receive a stub containing the ip address of the remote machine where the actual object can be found. The RMI server copies the contents of the java.rmi.server.hostname property into the stubs it returns to clients, so if the java.rmi.server.hostname property is "" and it copies that to each stub it creates, each stub contains a reference to remote server with an IP address of "". By default the client jvm reacts to this by attempting to connect to the server object on the localhost, 127.0.0.1. To work around the problem, try this line of code before exporting any remote objects on the server side:
System.setProperty( "java.rmi.server.hostname", "192.168.RMIServer.IP" ) ;
This property will be automatically copied to all remote stubs exported on that server, and clients who receive that stub should then be able to reach the remote server ( assuming any firewalls are configured correctly ).

java.rmi.ConnectException: Connection refused to host and java.rmi.UnmarshalException: Error unmarshaling return header;

I've been learning about RMI and I started with the Hello World program, which I got to work, and then began using other sample programs which all worked. (well there were errors, but I debugged them with the help of google/stackoverflow). and now I began writing my own project, which is basically a Traveling Salesman implementation that offloads the intense computation to a server.
Everything was working fine, when suddenly all my server RMI implementations broke. ie. when I run computeEngine from Eclipse as an RMI application (I use the RMI plugin), I get either the error:
java.rmi.ConnectException: Connection refused to host
or the error:
java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is: java.io.EOFException
I have 4-5 different RMI applications that were all working and then all of a sudden the "ComputeEngine.java" file which I run on the server started returning one of these 2 errors for every single one of my applications.
Note: since I am testing these applications, I use "localhost" as my server hostname. In otherwords, the server and the client are the same machine.
Things I have tried:
I have checked my etc/hosts/ file and found that 127.0.0.1 is set as localhost. I also created a new machine entitled "virtualmachine" and used my public IP address. Both did not work.
I have double and triple checked my server.policy and client.policy files, and both seem to be fine.
I have tried running the RMI application from terminal (instead of using the RMI plugin from eclipse) and I get the same errors
I quit all java processes and reran everything making sure I started the server first (other threads suggested that these errors come from running the client first)
I've portscanned myself and port 1099 (the default rmi port) says "LISTEN" when I run my server (even though the server is returning an exception).
I've tried changing java.rmi.server.hostname, but nothing has seemed to help so far.
I'm not understanding how I'm not getting connection to host when I am running both the server and client on the same computer.
I preemptively apologize from being sucky at RMI and Java and missing some likely obvious solution.
Should I include any source code from what I have been trying to run?
EDIT: Here is the stack trace:
ComputeEngine exception:
java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is:
java.io.EOFException
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:227)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:377)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at engine.ComputeEngine.main(ComputeEngine.java:33)
Caused by: java.io.EOFException
at java.io.DataInputStream.readByte(DataInputStream.java:267)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:213)
... 3 more
Thank You!
EDIT 2:
I noticed that if I restarted the RMIregistry when I started the application (as in, I selected the option in the Eclipse RMI plugin that restarted the rmiregistry) I would get a ClassNotFoundError for a class that is in my 'codebase.jar'.
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: compute.Compute
Any ideas?

Categories