Detach and attach RServe connection: Cannot connect - java

I am trying to detach and then attach an RServe session from Java. Connecting to RServe works flawlessly, but attaching causes an exception.
package com.company.korana.r_interface;
import org.rosuda.REngine.Rserve.RConnection;
import com.company.korana.config.Config$;;
public class RToast {
public static void main(String[] args) throws Exception {
RConnection rConnection = new RConnection(Config$.MODULE$.rserveHost(), Config$.MODULE$.rservePort());
rConnection.assign("testVariable", "hello from java");
rConnection.eval("print('Hi R console from java')"); // <--- this is visible in the R console
org.rosuda.REngine.Rserve.RSession sessionHandle = rConnection.detach();
rConnection = sessionHandle.attach(); // <---- this throws
System.out.println(rConnection.eval("testVariable").asString());
}
}
Exception in thread "main" org.rosuda.REngine.Rserve.RserveException:
Cannot connect: Connection refused: connect at
org.rosuda.REngine.Rserve.RConnection.(RConnection.java:90) at
org.rosuda.REngine.Rserve.RConnection.(RConnection.java:66) at
org.rosuda.REngine.Rserve.RSession.attach(RSession.java:36) at
com.company.korana.r_interface.RToast.main(RToast.java:16) Caused by:
java.net.ConnectException: Connection refused: connect at
java.net.DualStackPlainSocketImpl.connect0(Native Method) at
java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source) at
java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) at
java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) at
java.net.AbstractPlainSocketImpl.connect(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.(Unknown Source) at
java.net.Socket.(Unknown Source) at
org.rosuda.REngine.Rserve.RConnection.(RConnection.java:85) ...
3 more
The Rserve is running on localhost with the default port.
EDIT:
I'm using the following maven artifact:
<dependency>
<groupId>org.rosuda.REngine</groupId>
<artifactId>Rserve</artifactId>
<version>1.8.1</version>
</dependency>

After inspection of the sources, it turns out that Rserve sessions, when detached, listen on a randomly allocated port.
Rserv.c, line 1781
while ((port = (((int) random()) & 0x7fff)+32768)>65000) {};
So the port that needs to be reachable between the client and Rserve is something between 32768 and 65000. In my case, this didn't work because I was using docker.
EDIT: I built a solution to use Rserve with docker without opening a huge range of ports (which does not work nicely with docker). The snipper below replaces my install.packages("Rserve"):
RUN wget https://www.rforge.net/src/contrib/Rserve_1.8-5.tar.gz
RUN tar -xf Rserve_1.8-5.tar.gz
RUN rm Rserve_1.8-5.tar.gz
RUN sed -i '1763s/.*/\t\tint port = 53000;/' /Rserve/src/Rserv.c
RUN sed -i '1781s/.*//' /Rserve/src/Rserv.c
RUN sed -i '1793s/.*/\t\tif (port>53100) {/' /Rserve/src/Rserv.c
RUN tar -czvf Rserve_1.8-5.tar.gz /Rserve
RUN R CMD INSTALL Rserve_1.8-5.tar.gz
This modifies the Rserve sources so that ports are taken in the range [53000, 53100[ which is sufficient in my case.

Related

ConnectionException using Java MariaDB Connector

i want to establish a connection between my Java Program and my Database created with MariaDB on a different server (not localhost). Everything is fine with the ServerIP, Databasename, User and Password.
But i get this error:
Exception in thread "main" java.sql.SQLNonTransientConnectionException: Could not connect to address=(host=MY_SERVER_IP)(port=3306)(type=master) : Connection timed out: connect
at org.mariadb.jdbc.internal.SQLExceptionMapper.get(SQLExceptionMapper.java:136)
at org.mariadb.jdbc.internal.SQLExceptionMapper.throwException(SQLExceptionMapper.java:106)
at org.mariadb.jdbc.Driver.connect(Driver.java:106)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at MySQL_Tester.LoadDriver.main(LoadDriver.java:11)
Caused by: org.mariadb.jdbc.internal.common.QueryException: Could not connect to address= (host=MY_SERVER_IP)(port=3306)(type=master) : Connection timed out: connect
at org.mariadb.jdbc.internal.mysql.MySQLProtocol.connectWithoutProxy(MySQLProtocol.java:629)
at org.mariadb.jdbc.internal.common.Utils.retrieveProxy(Utils.java:541)
at org.mariadb.jdbc.Driver.connect(Driver.java:101)
... 3 more
Caused by: java.net.ConnectException: Connection timed out: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(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 org.mariadb.jdbc.internal.mysql.MySQLProtocol.connect(MySQLProtocol.java:288)
at org.mariadb.jdbc.internal.mysql.MySQLProtocol.connectWithoutProxy(MySQLProtocol.java:624)
... 5 more
My Code:
package MySQL_Tester;
import java.sql.*;
public class LoadDriver {
static Connection sqlHandler = null;
public static void main(String[]args) throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException {
Class.forName("org.mariadb.jdbc.Driver").newInstance();
sqlHandler=DriverManager.getConnection("jdbc:mysql://MY_SERVER_IP/DATABASENAME?user=USERNAME&password=PASSWORD");
}}
All the versions i use:
MariaDB: 10.1.44
MariaDB-Java-Connector: mariadb-java-client.1.2.0.jar
Java Version: Version 8 Update 161
Eclipse Version: 2019-03 (4.11.0)
You must update your connection string with the real values.
Thank you for your answer davidbuzatto but the problem was easier to solve than i expected.
Here is a Guide how i solved this problem for me:
Step 1: Check your MySQL-Config File with (nano /etc/mysql/my.cnf in Ubuntu)
replacing bind-adress: 172.0.0.1 with bind-adress: 0.0.0.0
When this doesnt help... For me it didnt help....
Step 2: Check the Firewall Settings on your Server and allow the access to the MySQL Server
When this also doesnt help... For me it didnt....
Step 3: Grant Access to your MySQL-Database
Use this MySQL-Query: GRANT ALL ON yourDatabasename.* to yourUser#yourIP identified by 'passwordOfTheUser';

Linux bash: java.net.ConnectException: Connection refused

I have a java program Read which reads file from an URL looks like this:
file://myhost/system.log
On Windows I use this command:
java Read "file://myhost/system.log"
and it works flawlessly.
But on Linux when I try to use the same command it gives me this error:
Exception in thread "main" java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at sun.net.ftp.impl.FtpClient.doConnect(Unknown Source)
at sun.net.ftp.impl.FtpClient.tryConnect(Unknown Source)
at sun.net.ftp.impl.FtpClient.connect(Unknown Source)
at sun.net.ftp.impl.FtpClient.connect(Unknown Source)
at sun.net.www.protocol.ftp.FtpURLConnection.connect(Unknown Source)
at sun.net.www.protocol.ftp.FtpURLConnection.getInputStream(Unknown Source)
at java.net.URL.openStream(Unknown Source)
at read.readInput(ReadHTML.java:53)
at read.readInput.main(ReadHTML.java:76)
Any ideas?
UPDATE:
I think I found the problem:
myhost is not mounted on the Linux machine so that it cannot connect to it by using file://...
Thanks for all the answers, guys!
This is because your program (by virtue of using a file URL on a Linux OS) is attempting to open an FTP connection to the host specified in the URL. The establishment of the FTP connection fails.
This could be due to a variety of issues. Try connecting with ftp directly:
ftp myhost
And I'm guessing it'd fail as well. Do you have an FTP server installed & running?
One of the possible reason can be that hosts.allow does not have entry of your machine.
I suspect you just need a third /. The correct syntax for file uris is file://[path] but [path] should begin with a /.

Java RMI and ClassNotFoundException

I am just starting to learn how to use RMI, and I have a question. I have the following directory structure:
compute.jar
client
|
org\examples\rmi\client
|--> ComputePi // client main
|--> Pi // implements Task
org\examples\rmi\compute
|--> Compute // interface
|--> Task // interface
server
|
org\examples\rmi\engine
|--> ComputeEngine // server main, implements Compute
org\examples\rmi\compute
|--> Compute // interface
|--> Task // interface
Here's the main method in the ComputePi class:
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
try {
String name = "Compute";
// args[0] = 127.0.0.1, args[1] is irrelevant
Registry registry = LocateRegistry.getRegistry(args[0], 0);
Compute comp = (Compute) registry.lookup(name);
Pi task = new Pi(Integer.parseInt(args[1]));
BigDecimal pi = comp.executeTask(task);
System.out.println(pi);
}
catch (Exception e) {
System.err.println("ComputePi exception:");
e.printStackTrace();
}
Here's the main method in the ComputeEngine class:
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
try {
String name = "Compute";
Compute engine = new ComputeEngine();
Compute stub = (Compute) UnicastRemoteObject.exportObject(engine, 0);
Registry registry = LocateRegistry.getRegistry();
registry.rebind(name, stub);
System.out.println("ComputeEngine bound.");
}
catch (Exception e) {
System.err.println("ComputeEngine exception: ");
e.printStackTrace();
}
Here's the executeTask method, also in the ComputeEngine class:
public <T> T executeTask(Task<T> task) throws RemoteException {
if (task == null) {
throw new IllegalArgumentException("task is null");
}
return task.execute();
}
The RMI registry and server start up just fine. Here are the params for the server:
C:\Users\Public\RMI\server>set CLASSPATH=
C:\Users\Public\RMI\server>start rmiregistry
C:\Users\Public\RMI\server>java -Djava.rmi.server.codebase="file:/C:/Users/Public/RMI/compute.jar" -Djava.rmi.server.hostname=127.0.0.1 -Djava.security.policy=server.policy org.examples.rmi.engine.ComputeEngine
Here are the params for the client:
C:\Users\Public\RMI\client>java -Djava.rmi.server.codebase="file:/C:/Users/Public/RMI/compute.jar" -Djava.security.policy=client.policy org.examples.rmi.client.ComputePi 127.0.0.1 45
However, I get the following exception when I try to run the client:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: org.examples.rmi.client.Pi
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
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.executeTask(Unknown Source)
at org.examples.rmi.client.ComputePi.main(ComputePi.java:38)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: org.examples.rmi.client.Pi
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.examples.rmi.client.Pi
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at sun.rmi.server.LoaderHandler.loadClass(Unknown Source)
at sun.rmi.server.LoaderHandler.loadClass(Unknown Source)
at java.rmi.server.RMIClassLoader$2.loadClass(Unknown Source)
at java.rmi.server.RMIClassLoader.loadClass(Unknown Source)
at sun.rmi.server.MarshalInputStream.resolveClass(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at sun.rmi.server.UnicastRef.unmarshalValue(Unknown Source)
... 11 more
But if I add the Pi.class file to the server directory:
server
|
org\examples\rmi\engine
|--> ComputeEngine // server main, implements Compute
org\examples\rmi\compute
|--> Compute // interface
|--> Task // interface
org\examples\rmi\client
|--> Pi // same as Pi for client
The program works. My question is, does Pi.class really need to be on the server for my program to work? My understanding is (and please correct me if I'm wrong) that I send an instance of that class to the server, and the server would know what to do with it, i.e. it doesn't care about the implementation. Can someone explain how RMI is working in my case? I really appreciate it. Thanks!
I tried this example with two PC in same network. One with Java 1.7.0_40 working as server, another with Java 1.7.0_45 as client. Both PCs are Windows based. I met the same problem raised by denshaotoko.
The solution is:
Server side:
C:\>start rmiregistry -J-Djava.rmi.server.useCodebaseOnly=false
The -J-Djava.rmi.server.useCodebaseOnly option is needed for Java 7 since the default value is true, which means the RMI Registry will not look for other code base except the directory it is started from. Then the next step starting the server will fail. Details see here: http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/enhancements-7.html
C:\>java -cp c:\rmi;c:\rmi\compute.jar -Djava.rmi.server.useCodebaseOnly=false -Djava.rmi.server.codebase=file:/c:/rmi/compute.jar -Djava.rmi.server.hostname=192.168.1.124 -Djava.security.policy=c:\rmi\server.policy engine.ComputeEngine
Again the java.rmi.server.useCodebaseOnly should be set to false. Otherwise the server won't use the codebase provided by the client. Then client side will get the class not found exception. The hostname of 192.168.1.124 is the server's IP address
You should get "ComputeEngine bound"
Client side:
C:\>java -cp c:\rmi;c:\rmi\compute.jar -Djava.rmi.server.codebase=http://54.200.126.244/rmi/ -Djava.security.policy=c:\rmi\client.policy client.ComputePi 192.168.1.124 45
I trid the file:/ URL but not successful. I think the reason is simple. There're so many security limits that make the server not possible to access a file on the client PC. So I put the Pi.class file on my web server which is at http://54.200.126.244 under rmi directory. My web server use Apache. Any PC can access http://54.200.126.244/rmi/ so the problem is solved cleanly.
Finally, you should be able to start the rmiregistry, the server and the client from any directory using the same commands. Otherwise, some settings may still not be correct even if you can succeed. For example, if you start rmiregistry from the directory contain the "compute" directory (in my case is C:\rmi), the rmiregistry will directly load Compute.class and Task.class from it's starting directory, so the setting of -Djava.rmi.server.codebase=file:/c:/rmi/compute.jar become useless.
You are trying to send a serialized object of a class that is unknown to the server.
When you execute:
Pi task = new Pi(Integer.parseInt(args[1]));
BigDecimal pi = comp.executeTask(task);
The server doesn't really know what is Pi. And since the Pi class is a part of your API, it should be loaded on server, too.
When I have an application that needs to execute something remotely, using for example RMI, Spring Remoting or similar, I divide my project in 3 projects: API, Server and Client. The API project will have all interfaces and model classes relevant to the functionality (this project will result in a jar, and is more or less like your computer JAR). The server will import the API JAR, will implement the interfaces and make the service available through an Remote layer (like you did with your server), and the client as you did with your client.
When you work with serialization, the class itself must be known by both sides. What is then transferred is the state of the objects in order to rebuild it on the other side.
Serialization is the mechanism used by RMI to pass objects between
JVMs, either as arguments in a method invocation from a client to a
server or as return values from a method invocation.
A bit of Serialization on RMI By William Grosso (October 2001). And here a bit more info.
My question is, does Pi.class really need to be on the server for my program to work? My understanding is (and please correct me if I'm wrong) that I send an instance of that class to the server, and the server would know what to do with it, i.e. it doesn't care about the implementation.
You understood correctly. Pi.class doesn't need to be on server when you compile it, but the server does need to download it at runtime! (Pi must be serializable)
The question is: How does a server know where to download the Pi.class when does he need it?
And the answer is: by the value of java.rmi.server.codebase setting provided by the client. The client must set the java.rmi.server.codebase option. You have to say where the Pi.class is. It is a common habit to put a copy of Pi.class in a public directory for deployment. Therefore the complete solution is:
The Structure:
compute.jar
client\
|-org\
| |-examples\
| |-rmi\
| |client\
| |--> ComputePi // client main
| |--> Pi // implements Task
|-deploy\
| |-org\
| |-examples\
| |-rmi\
| |-client\ // directory that will contain the deployment copy of Pi.class
|--> client.policy
server\
|-org\
| |-examples\
| |-rmi\
| |-engine\
| |--> ComputeEngine // server main, implements Compute
|--> server.policy
where compute.jar is a jar file previously created
cd C:\Users\Public\RMI\
javac compute\Compute.java compute\Task.java
jar cvf compute.jar compute\*.class
Did you set correctly the package and import commands in your java files? Because you modified the original structure of the tutorial...
Compile the Server:
C:\Users\Public\RMI\> cd server
C:\Users\Public\RMI\server> javac -cp ..\compute.jar org\examples\rmi\engine\ComputeEngine.java
Compile the Client:
C:\Users\Public\RMI\> cd client
C:\Users\Public\RMI\client> javac -cp ..\compute.jar org\examples\rmi\client\ComputePi.java org\examples\rmi\client\Pi.java
Move the Pi.class into the deploy directory
C:\Users\Public\RMI\> cp client\org\examples\rmi\client\Pi.class client\deploy
Run the rmi registry. If you are using java 7 set the option -J-Djava.rmi.server.useCodebaseOnly=false, as suggested by muyong
C:\Users\Public\RMI\> start rmiregistry -J-Djava.rmi.server.useCodebaseOnly=false
Run the server. If you are using java 7 set the option -J-Djava.rmi.server.useCodebaseOnly=false, as suggested by muyong
C:\Users\Public\RMI\> cd server
C:\Users\Public\RMI\server> java -cp .;..\compute.jar
-Djava.rmi.server.useCodebaseOnly=false
-Djava.rmi.server.codebase=file:/c:/Users/Public/RMI/compute.jar
-Djava.rmi.server.hostname=127.0.0.1
-Djava.security.policy=server.policy
org.examples.rmi.engine.ComputeEngine
Run the Client. NOTE: watch out the java.rmi.server.codebase setting (REMEMBER the conclusive /)
C:\Users\Public\RMI\> cd client
C:\Users\Public\RMI\client> java -cp .;..\compute.jar
-Djava.rmi.server.codebase=file:/c:/Users/Public/RMI/client/deploy/
-Djava.security.policy=client.policy
org.examples.rmi.client.Compute.Pi 127.0.0.1 45
Let me know if it works!
P.s. I don't use Windows OS but Linux, I could have made confusion between '\' and '/'
from jdk 1.7 the default value of useCodebaseOnly is true, that mean it wont look for other codebase unless it is in the same directory.
Set this vm argument -Djava.rmi.server.useCodebaseOnly=false for running both server and client and also provide the path to codebase and hostname as well. See below below examples.
Below is my implementation and it's according to my directory structure. For running in windows replace : (colon) with ; (semi-colon).
java -cp classes:classes/compute.jar
-Djava.rmi.server.useCodebaseOnly=false -Djava.rmi.server.codebase=url:http://localhost:4800/ -Djava.rmi.server.hostname=localhost -Djava.security.policy=client.policy client.ComputePi localhost 45
I think the codebase that you specify for the client is not correct:
-Djava.rmi.server.codebase="file:/C:/Users/Public/RMI/compute.jar"
This will not help the server to find client.Pi .
The "Java Tutorial RMI" specifies
-Djava.rmi.server.codebase=file:/c:/home/jones/public_html/classes/
and that's the dir under which there is client/Pi.class (i.e. if one follows the tutorial, where "jones" wrote the client).
Unfortunately, even when following my own advice, meaning in my situation specifying
-Djava.rmi.server.codebase=file:/h:/rmi-example/jones/src/
when I start the client, I get the same exception as you do.
Haven't solved it yet. I'm hoping java option -verbose:class will shed some light on the problem.
Press Win + R shortcut keys together on your keyboard. This will open the Run dialog. ...
Type the following command in the Run box: rundll32.exe sysdm.cpl,EditEnvironmentVariables
then give you current directory

Application Not Debugging in Eclipse

I am trying to run my Java application in debug mode in Eclipse, but it's not working. It was fine until yesterday when I could properly debug my application. I am able to run my application on the server ( Oracle OC4J Standalone Server 10.1.3) properly. Only while debugging, it continues for a long time and then shows a server time out error. I tried increasing the Server time out, but was of no use.
I also tried removing the Server and creating it again and restarting Eclipse. Is there something I could do about this?
Edit: Strack trace on trying to Run it as Remote Java Application
Exception Stack tace:
java.net.ConnectException: Connection refused: connect
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 org.eclipse.jdi.internal.connect.SocketTransportService$2.run(SocketTransportService.java:136)
at java.lang.Thread.run(Unknown Source)
There is an issue with OC4J's debug mode enabling. Sometimes I've noticed that after enabling it (via opmn.xml) it will work for a while then stop working. What I've found to actually work all the time is editing the /bin/oc4j.cmd file and adding the line:
set JVMARGS=-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=9009,suspend=y,server=y
then start a Remote debugging session from Eclipse on the port 9009

Java RMI (Server: TCP Connection Idle/Client: Unmarshalexception (EOFException))

I'm trying to implement Sun Tutorials RMI application that calculates Pi. I'm having some serious problems and I cant find the solution eventhough I've been searching the entire web and several javaskilled people.
I'm hoping you can put an end to my frustrations.
The crazy thing is that I can run the application from the cmd on my desktop computer. Trying the exact same thing with the exact same code in the exact same directories on my laptop produces the following errors. The problem occures when I try to connect the client to the server.
I don't believe that the error is due to my policyfile as I can run it on the desktop. It must be elsewhere. Have anyone tried the same and can you give me a hint as to where my problem is, please?
POLICYFILE SERVER:
grant
{
permission java.security.AllPermissions;
permission java.net.SocketPermission"*", "connect, resolve";
};
POLICYFILE CLIENT:
grant
{
permission java.security.AllPermissions;
permission java.net.SocketPermission"*", "connect, resolve";
};
______________________________________________
SERVERSIDE ERRORS:
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\Documents and Settings\STUDENT>cd\
C:\>start rmiregistry
C:\>java -cp c:\java;c:\java\compute.jar -Djava.rmi.server.codebase=file:/c:/jav
a/compute.jar -Djava.rmi.server.hostname=localhost -Djava.security.policy=c:/jav
a/servertest.policy engine.ComputeEngine
ComputeEngine bound
Exception in thread "RMI TCP Connection(idle)" java.security.AccessControlExcept
ion: access denied (java.net.SocketPermission 127.0.0.1:1440 accept,resolve)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkAccept(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.checkAcceptPermi
ssion(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.checkAcceptPermission(Unknown Sour
ce)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Sou
rce)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Sour
ce)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source
)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
_______________________________
CLIENTSIDE ERRORS:
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\Documents and Settings\STUDENT>cd\
C:\>java -cp c:\java;c:\java\compute.jar -Djava.rmi.server.codebase=file:\C:\jav
a\files\ -Djava.security.policy=c:/java/clienttest.policy client.ComputePi local
host 45
ComputePi exception:
java.rmi.UnmarshalException: Error unmarshaling return header; nested exception
is:
java.io.EOFException
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unkn
own Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at $Proxy0.executeTask(Unknown Source)
at client.ComputePi.main(ComputePi.java:18)
Caused by: java.io.EOFException
at java.io.DataInputStream.readByte(Unknown Source)
... 6 more
C:\>
Thanks in advance
Perry
Your server didn't have permission to accept a connection from that client.
Ergo your policy file wasn't where you said it was, or wasn't loaded for some other reason.
Run it with -Djava.security.debug=access,failure and you will see what protection domain you were in when the security exception occurred, and what permissions it had.
java -cp c:\java;c:\java\compute.jar -Djava.rmi.server.codebase=file:/c:/java/compute.jar -Djava.rmi.server.hostname=localhost -Djava.security.policy=c:/java/servertest.policy engine.ComputeEngine
NB a file: codebase cannot work if it refers to a local filesystem, unless the client is also in the same machine, which makes RMI fairly pointless. Codebase URLs need to refer to locations that are accessible by the client. You can use shared file systems but you must provide a URL that is usable by the client. The server doesn't use its own codebase URL at all.
I tried the same and I found that Java simply ignored the policy file, no matter where I put it or what I put into it or which option I used to make the VM pick it up.
In the end, I create my own SecurityManager in the code and did everything manually.

Categories

Resources