RMI - Unmarshalled Exception - java

I can't seem to get this working. I'm just look at it for basic instruction for a lab, but I've no experience with RMI at all. I can't seem to get why I'm getting the error.
Server
public static void runServer() {
// Install security manager, if none is present
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
try {
Registry registry = LocateRegistry.getRegistry();
System.out.println("Reg: " + registry.toString());
String name = "Server";
Server server = new Server();
I_Server stub = (I_Server) UnicastRemoteObject.exportObject(server, 0);
registry.rebind(name, stub);
System.out.println("All is well :-)\n");
} catch (RemoteException re) {
System.err.println("Remote Exception in DisplayGetEngine.main()\n");
re.printStackTrace();
}
}
}
I have the following run commands and arguments in NetBeans
Arguments: -cp C:\rmi\Server\src;C:\rmi\Server\dist\Server.jar -Djava.rmi.server.codebase=file:/C:/rmi/Server/dist/Server.jar
Working Directory: C:\rmi\Server
My stacktrace is, at the rebind method.
Reg: RegistryImpl_Stub[UnicastRef [liveRef: [endpoint:[10.50.18.205:1099](remote),objID:[0:0:0, 0]]]]
Remote Exception in DisplayGetEngine.main()
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: server.I_Server
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:419)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267)
at sun.rmi.transport.Transport$1.run(Transport.java:177)
at sun.rmi.transport.Transport$1.run(Transport.java:174)
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:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:273)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:251)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:377)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at server.Server.runServer(Server.java:50)
at server.Server.main(Server.java:31)
If I don't run rmiregistry, this is my stacktrace
Remote Exception in DisplayGetEngine.main()
java.rmi.ConnectException: Connection refused to host: 10.50.18.205; nested exception is:
java.net.ConnectException: Connection refused: connect
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.newCall(UnicastRef.java:340)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at server.Server.runServer(Server.java:50)
at server.Server.main(Server.java:31)

Try calling createRegistry() first to make sure that you have a running registry. Also, port 0 should be a reserved port so you won't be able to make your server listen on that particular port. Try the default one 1099.

There is no problem in running rmiregistry. If you look into the stacktrace closely,the problem seems to be ClassNotFoundException while the arguments are being unmarshalled in the rmi registry. You will have to check the code base of the RMI server whether server.I_Server class is present in the Server.jar while running it in the classpath.
From RMI FAQs
A.4 Why am I getting a ClassNotFoundException?
Most likely the java.rmi.server.codebase property has not been set (or has not been set correctly) on a VM that is exporting your remote object(s). Please take a look at our tutorial, Dynamic code downloading using Java RMI (Using the java.rmi.server.codebase Property).

The issue was in the build file. I needed to insert this statement.
<target name="startRMI" depends="init">
<exec executable="C:\Program\Files\Java\jdk1.7.0_51\jre\bin\rmiregistry"
dir="${build.classes.dir}"></exec>
</target>

Related

NameNotFoundException doing JNDI lookup to remote EJB in production JBoss (works locally)

An application (e.g app.EAR) is deployed to a JBoss in my own machine and works fine. When I deploy it to a remote JBoss it is deployed, but when I try to access a functionality that needs a JNDI lookup to a remote EJB I get NameNotFoundException. So, it seems that it was unable to find the requested service. How come? If it works locally?
The dependency with the remote EJB interface is in the lib folder inside the EAR and of course is annotated with #Remote. The JBoss is exactly the same as the production one (I copied the whole JBoss from production to my machine to check if there is any configuration missing).
My lookup code is like this:
private Object lookup(String resourceName, String loginData) {
if (isPropagateUserCredentials() && (loginData == null || loginData.trim().equals(""))) {
throw new MyInfraConfigException("somemessage");
}
Properties envProperties = new Properties();
envProperties.putAll(this.jndiProperties);
if (loginData != null && !loginData.equals("")) {
envProperties.put(Context.SECURITY_PRINCIPAL, loginData);
envProperties.remove(Context.SECURITY_CREDENTIALS);
}
Context context = null;
try {
context = new InitialContext(envProperties);
return context.lookup(resourceName);
} catch (NameNotFoundException e){
String message = "Resource "+resourceName+" not found.";
LoggerFactory.getInstance(this.getClass().getName()).error(message, e);
throw new com.mypackage.NameNotFoundException(message, e);
} catch (NamingException e) {
String message = "Failed to find resource with JNDI: "+e.getMessage();
LoggerFactory.getInstance(this.getClass().getName()).error(message, e);
throw new com.mypackage.NamingException(message, e);
} finally{
if(context!=null){
try {
context.close();
} catch (NamingException e) {
e.printStackTrace();
}
}
}
}
The resourceName is ExternalResource.
The stacktrace is below:
29/06/2015 10:30:43 oracle.j2ee.clustering.ClusteringMessages warningInOpmnGetServers
AVISO: Error in obtaining server list from OPMN on host XX.XXX.XXX.XXX:XXXX. Please verify that OPMN is running.
javax.naming.NameNotFoundException: ExternalResource not found
at com.evermind.server.rmi.RMIClientContext.lookup(RMIClientContext.java:60)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at br.teste.TestaJNDI.main(TestaJNDI.java:33)
Any clues?
UPDATE
Made an external simple java application in order to try to connect to the server and understand the cause of the problem. In fact, the problem is that I am getting a connection timeout:
javax.naming.CommunicationException: Connection timed out [Root exception is java.net.ConnectException: Connection timed out]
at com.evermind.server.rmi.RMIClient.lookup(RMIClient.java:311)
at com.evermind.server.rmi.RMIClientContext.lookup(RMIClientContext.java:59)
at javax.naming.InitialContext.lookup(Unknown Source)
at br.teste.TestaJNDI.listaUFs(TestaJNDI.java:55)
at br.teste.TestaJNDI.main(TestaJNDI.java:37)
Caused by: java.net.ConnectException: Connection timed out
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at com.evermind.server.rmi.RMIClientConnection.createSocket(RMIClientConnection.java:802)
at oracle.oc4j.rmi.ClientSocketRmiTransport.createNetworkConnection(ClientSocketRmiTransport.java:59)
at oracle.oc4j.rmi.ClientRmiTransport.connectToServer(ClientRmiTransport.java:75)
at oracle.oc4j.rmi.ClientSocketRmiTransport.connectToServer(ClientSocketRmiTransport.java:69)
at com.evermind.server.rmi.RMIClientConnection.connect(RMIClientConnection.java:765)
at com.evermind.server.rmi.RMIClientConnection.sendLookupRequest(RMIClientConnection.java:247)
at com.evermind.server.rmi.RMIClientConnection.lookup(RMIClientConnection.java:231)
at com.evermind.server.rmi.RMIClient.lookup(RMIClient.java:302)
... 4 more
This might be a network communication issue. I would check if the server does allow for communication on the remoting ports. Try telnet the server, if its configured to accept these requests:
telnet <server> <port>
If using default ports, I think this should be 4447. If this connection fails then answer the following:
1. Is there no firewall that might be blocking this communication.
2. Are you using the correct port as configured by your production server.
There could really be other reasons for the fail, but that would be a starting point.

How to set a custom port for RMI regisrty?

In my RMI program I want to set up my RMI registry on the port 8080, but when I do it, I get an exception.
Here is my server code
public class Server {
public static void main(String[] args) {
try {
LocateRegistry.createRegistry(8080);
MathServerImpl mathServer = new MathServerImpl();
Naming.rebind("MathServer", mathServer);
System.out.println("Math Server has started and is running");
} catch (RemoteException | MalformedURLException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
The code works properly for the port 1099, which is it's default port as far as I know, but for this case it gives me a java.net.ConnectException, and here is the log.
java.rmi.ConnectException: Connection refused to host: 10.100.25.173; 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.newCall(UnicastRef.java:341)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at java.rmi.Naming.rebind(Naming.java:177)
at server.Server.main(Server.java:16)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:579)
at java.net.Socket.connect(Socket.java:528)
at java.net.Socket.<init>(Socket.java:425)
at java.net.Socket.<init>(Socket.java:208)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:147)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
... 11 more
You are creating a registry on port 8080 but then attempting to rebind your object in the default registry on port 1099. You need to either:
pass a full URL to Naming.rebind including the port number, i.e. //localhost:8080/MathServer or
save a reference to the Registry object returned by LocateRegistry.createRegistry and bind the object using that registry's instance methods rather than the static methods of Naming
Similarly, you will need to use the full //localhost:8080/MathServer URL form in your clients when they lookup the object, to make sure they're talking to the right registry.
Naming.rebind("MathServer", mathServer);
Change that to
Naming.rebind("//localhost:8080/MathServer", mathServer);
If you are linux Ubuntu user then while starting RMI registry use command
rmiregistry 8080 &
For Windows
start rmiregistry 8080

error executing Head First EJB first example

I am following Head First EJB. I know it has EJB 2.0 which is old as now EJB 3.1 is in. But I consider Head first book a good book for learning for amateurs like us.
I am using J2ee 1.3.1 RI and jdk 1.4. I ran the "deploy" tool to deploy by EJB and now I have a ejb client JAVA program given below:
import javax.naming.*;
import java.rmi.*;
import javax.rmi.*;
import headfirst.*;
import javax.ejb.*;
import java.util.*;
public class AdviceClient {
public static void main(String[] args){
new AdviceClient().go();
}
public void go(){
try{
Properties props=new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
//props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
//env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
//props.setProperty(Context.INITIAL_CONTEXT_FACTORY,"com.sun.enterprise.naming.SerialInitContextFactory");
props.setProperty(Context.PROVIDER_URL,"rmi://localhost:1050");
//props.setProperty("java.naming.provider.url","rmi://localhost:1099");
Context ic = new InitialContext(props);
Object o = ic.lookup("Advisor");
AdviceHome home = (AdviceHome)PortableRemoteObject.narrow(o,AdviceHome.class);
Advice advisor = home.create();
System.out.println(advisor.getAdvice());
}
catch(Exception ex){
ex.printStackTrace();
}
}
}
Following the book, I compiled the program. The "Properties" part is something not mentioned in the example. I got it from some other examples on the web. Now, that when I am executing the client, am getting the following error:
F:\EJBProject\advice>java -classpath AdviceAppClient.jar;. AdviceClient
javax.naming.CommunicationException [Root exception is java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:
java.net.SocketTimeoutException: Read timed out]
at com.sun.jndi.rmi.registry.RegistryContext.lookup(Unknown Source)
at com.sun.jndi.rmi.registry.RegistryContext.lookup(Unknown Source)
at javax.naming.InitialContext.lookup(Unknown Source)
at AdviceClient.go(AdviceClient.java:26)
at AdviceClient.main(AdviceClient.java:11)
Caused by: java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:
java.net.SocketTimeoutException: Read timed out
at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
at sun.rmi.server.UnicastRef.newCall(Unknown Source)
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
... 5 more
Caused by: java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
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)
Please help. I am stuck up badly here. I wanted to sit for the OCBCD exam!
Regards,
Shouvanik
Finally Solved.
If you hit a roadblock while running the first EJB example simply follow these steps
to run the first example of HeadFirst EJB.
Softwares
1. j2sdk1.4.1 - jdk
2. j2sdkee1.3.1 - j2ee RI
3. CMD (command prompt)
Compile all the classes using c:\j2sdkee1.3.1\lib\j2ee.jar library.
Now, create a App and deploy EJB inside RI. download the application client as shown in the book.
Now, comes the tricky part.
Compile client class using the following jars
javac -classpath AdviceAppClient.jar;c:\j2sdkee1.3.1\lib\j2ee.jar AdviceClient.java
Next, run the client as follows
java -cp AdviceAppClient.jar;c:\j2sdkee1.3.1\lib\j2ee.jar;c:\j2sdk1.4.1\jre\lib\rt.jar;. AdviceClient

How to configure Jaql with an existing Hadoop Cluster and use jaql oprators to filter the result?

When I read a file from hdfs by giving it proper path the file is read successfully but when I try to use transform operator of jaql it throws an exception as given below and if I try to execute the code on JAQL shell then an exception is thrown of job.jar but even after adding the jar the exception is still thrown. if anybody knows that somehow JAQL is not configured properly with existing hadoop cluster or the exception is due to some other cause?
My code is:
jaql.setQueryString("read(lines('hdfs://hadoopserver:54310/dbreports/reports.json'," +
"{format: 'org.apache.hadoop.mapred.TextInputFormat',converter: 'com.ibm.jaql.io.hadoop.converter.FromJsonTextConverter'})) -> transform $.store_number;");
System.out.println("jaql running successfully....");
JsonValue jv = jaql.evaluate();
System.out.println("value is "+jv);
when run it throws an exception as:
Exception in thread "Thread-38" java.lang.NoClassDefFoundError: org/apache/commons/httpclient/HttpMethod
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:295)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.httpclient.HttpMethod
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
at sbt.PlayCommands$$anonfun$61$$anonfun$63$$anon$2$$anonfun$loadClass$1.apply(PlayCommands.scala:563)
at sbt.PlayCommands$$anonfun$61$$anonfun$63$$anon$2$$anonfun$loadClass$1.apply(PlayCommands.scala:563)
at scala.Option.map(Option.scala:133)
at sbt.PlayCommands$$anonfun$61$$anonfun$63$$anon$2.loadClass(PlayCommands.scala:563)
... 1 more
java.io.IOException: Job failed!
..........
Do anybody knows what it is that i'm missing?

Rmi connection refused with localhost

I have a problem using java rmi:
When I'm trying to run my server, I get a connectException (see below).
Exception happens when executing the rebind method:
Runtime.getRuntime().exec("rmiregistry 2020");
MyServer server = new MyServer();
Naming.rebind("//localhost:2020/RemoteDataPointHandler", server);
when using rmi://localhost:2020/RemoteDataPointHandler instead, it doesn't work either. Also using the default port does not work. I also tried using the 127.0.0.1 ip-address, but with the same effect.
my runtime args:
-Djava.security.policy=java.security.AllPermission
Exception in thread "main" java.rmi.ConnectException: Connection refused to host: localhost; nested exception is:
java.net.ConnectException: Connection refused
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at java.rmi.Naming.rebind(Naming.java:160)
at be.fortega.knx.server.Main.(Main.java:25)
at be.fortega.knx.server.Main.main(Main.java:16)
Caused by: java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:433)
at java.net.Socket.connect(Socket.java:524)
at java.net.Socket.connect(Socket.java:474)
at java.net.Socket.(Socket.java:371)
at java.net.Socket.(Socket.java:184)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:569)
... 7 more
had a simliar problem with that connection exception. it is thrown either when the registry is not started yet (like in your case) or when the registry is already unexported (like in my case).
but a short comment to the difference between the 2 ways to start the registry:
Runtime.getRuntime().exec("rmiregistry 2020");
runs the rmiregistry.exe in javas bin-directory in a new process and continues parallel with your java code.
LocateRegistry.createRegistry(2020);
the rmi method call starts the registry, returns the reference to that registry remote object and then continues with the next statement.
in your case the registry is not started in time when you try to bind your object
It seems to work when I replace the
Runtime.getRuntime().exec("rmiregistry 2020");
by
LocateRegistry.createRegistry(2020);
anyone an idea why? What's the difference?
You need to have a rmiregistry running before attempting to connect (register) a RMI service with it.
The LocateRegistry.createRegistry(2020) method call creates and exports a registry on the specified port number.
See the documentation for LocateRegistry
One difference we can note in Windows is:
If you use Runtime.getRuntime().exec("rmiregistry 1024");
you can see rmiregistry.exe process will run in your Task Manager
whereas if you use Registry registry = LocateRegistry.createRegistry(1024);
you can not see the process running in Task Manager,
I think Java handles it in a different way.
and this is my server.policy file
Before running the the application, make sure that you killed all your existing
javaw.exe and rmiregistry.exe corresponds to your rmi programs which are
already running.
The following code works for me by using Registry.LocateRegistry() or
Runtime.getRuntime.exec("");
// Standard extensions get all permissions by default
grant {
permission java.security.AllPermission;
};
VM argument
-Djava.rmi.server.codebase=file:\C:\Users\Durai\workspace\RMI2\src\
Code:
package server;
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.Remote;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class HelloServer
{
public static void main (String[] argv)
{
try {
if(System.getSecurityManager()==null){
System.setProperty("java.security.policy","C:\\Users\\Durai\\workspace\\RMI\\src\\server\\server.policy");
System.setSecurityManager(new RMISecurityManager());
}
Runtime.getRuntime().exec("rmiregistry 1024");
// Registry registry = LocateRegistry.createRegistry(1024);
// registry.rebind ("Hello", new Hello ("Hello,From Roseindia.net pvt ltd!"));
//Process process = Runtime.getRuntime().exec("C:\\Users\\Durai\\workspace\\RMI\\src\\server\\rmi_registry_start.bat");
Naming.rebind ("//localhost:1024/Hello",new Hello ("Hello,From Roseindia.net pvt ltd!"));
System.out.println ("Server is connected and ready for operation.");
}
catch (Exception e) {
System.out.println ("Server not connected: " + e);
e.printStackTrace();
}
}
}
it seems that you should set your command as an String[],for example:
String[] command = new String[]{"rmiregistry","2020"};
Runtime.getRuntime().exec(command);
it just like the style of main(String[] args).

Categories