Java RMI ClassNotFound exception - java

I decided to write RMI (from the book) took code from the book too. i created the Stub with rmic, and started rmiregistry but when i dedided to write java Start Server i got the problem, actually here is my problem i faced with:
java -classpath D:\RMI AddServer
Exception:java.rmi.ServerException: RemoteException occurred in server thread; n
ested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested excep
tion is:
java.lang.ClassNotFoundException: AddServerImpl_Stub
PLease i need help, i lost lot of time because of this :(
AddServerIntf.java
package rmi.app;
import java.rmi.*;
public interface AddServerIntf extends Remote {
double add(double d1,double d2) throws RemoteException;}
AddServerImpl
package rmi.app;
import java.rmi.*;
import java.rmi.server.*;
public class AddServerImpl extends UnicastRemoteObject implements AddServerIntf {
public AddServerImpl() throws RemoteException {}
public double add(double d1, double d2) throws RemoteException {
return d1+d2;
}
}
AddServer
package rmi.app;
import java.net.*;
import java.rmi.*;
public class AddServer {
public static void main(String[] args) {
try {
AddServerImpl addServerImpl = new AddServerImpl();
Naming.rebind("AddServer", addServerImpl);
}
catch (Exception e){
System.out.println("Exception:"+e);
}
}
}
AddClient
package rmi.app;
import java.rmi.Naming;
public class AddClient {
public static void main(String[] args) {
try{
String addServerURL= "rmi://"+args[0]+ "/AddServer";
AddServerIntf addServer =(AddServerIntf)Naming.lookup(addServerURL);
System.out.println("The first number is:"+args[1]);
double d1= Double.valueOf(args[1]).doubleValue();
System.out.println("The second number is:"+args[2]);
double d2= Double.valueOf(args[2]).doubleValue();
System.out.println("the sum is:"+ addServer.add(d1,d2));
}
catch(Exception e){
System.out.println("Exception : "+ e);
}
}
}

I am writing a Java RMI application too and I went through a lot before being able to make it work. After a lot of research and try and error I got this "recipe":
Don't install SecurityManager;
Don't use policy files;
Make sure the classes you're moving from one VM to another are in
both client and server classpath (or in the same jar/war).
If you're using hibernate to make database access, put the jars in the
client too. Hibernate "changes" the original classes and the client
will need this to deserialize it;
If you're also using Spring on the server side you might include the spring-orm and spring-data-jpa jars in the client, if you experience ClassNotFoundException followed by JpaObjectRetrievalFailureException;
I am not running anything outside the jars (no rmi services at all);
I didn't create the stubs as I am using Java 6.
My server is purely doing this:
try {
try {
LocateRegistry.createRegistry(SERVER_PORT);
} catch (RemoteException e) {
LocateRegistry.getRegistry(SERVER_PORT);
e.printStackTrace();
}
System.setProperty("java.rmi.server.hostname", SERVER_HOST);
connectionRequestHandler = new ConnectionRequestHandlerImpl();
dataRequestHandler = new DataRequestHandlerImpl();
String rmiUrl = "rmi://" + SERVER_HOST + ":" + SERVER_PORT + "/";
Naming.rebind(rmiUrl + "ConnectionRequestHandler", connectionRequestHandler);
Naming.rebind(rmiUrl + "DataRequestHandler", dataRequestHandler);
} catch (RemoteException e1) {
e1.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
Then on client I am doing:
String rmiUrl = "rmi://" + SERVER_HOST + ":" + SERVER_PORT + "/";
try {
connectionRequestHandler = (ConnectionRequestHandler)Naming.lookup(rmiUrl + "ConnectionRequestHandler");
dataRequestHandler = (DataRequestHandler)Naming.lookup(rmiUrl + "DataRequestHandler");
} catch (MalformedURLException e) {
throw new RmiServicesDownException(e.getMessage());
} catch (RemoteException e) {
throw new RmiServicesDownException(e.getMessage());
} catch (NotBoundException e) {
throw new RmiServicesDownException(e.getMessage());
} catch (Exception e ){
e.printStackTrace();
return;
}
This is how it's working for me. Any other problems you may have are easy to solve compared to the first setup.

Short answer: the registry needs to have the stubs on its classpath.
Long answer: find an rmi tutorial from within the last 10 years which doesn't use rmic, cause you haven't need to do all that for a long time.

Change the AddServerImpl constructor to call super(0). Then you don't even need to generate a stub, let alone deploy it. See the preamble to the Javadoc of UnicastRemoteObject.

start rmiregistry from the server code directory. (or) Execute with -j option Please refer How do I set the classpath that rmiregistry uses? and javadoc reference [here]

Related

Java program terminates after registering Listeners

Hello people on the internet!
I have a problem with my code in java, I'm shure it's just a beginner error, but I can't quite get WHAT the problem is.
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Random;
public class MultiThreadChatClient
{
private static Socket clientSocket = null;
private static PrintStream os = null;
private static boolean closed = false;
private static void start()
{
int portNumber = 2222;
String host = "localhost";
System.out.println("Host=" + host + ", port=" + portNumber);
try
{
clientSocket = new Socket(host, portNumber);
os = new PrintStream(clientSocket.getOutputStream());
os.println("KeyListener ID: " + new Random().nextInt());
}
catch (UnknownHostException e)
{
System.err.println("Finner ikke hosten " + host);
}
catch (IOException e)
{
System.err.println("Error, fant ingen åpen server på " + host);
}
if ( clientSocket == null || os == null )
{
closed = true;
}
Listener.startListener();
}
public void stop()
{
closed = true;
os.close();
try
{
clientSocket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void send(String msg)
{
if (!closed)
{
os.println(msg);
}
}
public static void main( String[] args )
{
start();
}
}
And the class:
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;
import org.jnativehook.mouse.NativeMouseEvent;
import org.jnativehook.mouse.NativeMouseInputListener;
import org.jnativehook.mouse.NativeMouseWheelEvent;
import org.jnativehook.mouse.NativeMouseWheelListener;
public class Listener implements NativeKeyListener, NativeMouseInputListener, NativeMouseWheelListener
{
public void nativeKeyPressed(NativeKeyEvent e)
{
MultiThreadChatClient.send(NativeKeyEvent.getKeyText(e.getKeyCode()));
}
public void nativeKeyReleased(NativeKeyEvent e)
{
}
public void nativeKeyTyped(NativeKeyEvent e)
{
}
public void nativeMouseClicked(NativeMouseEvent e)
{
}
public void nativeMousePressed(NativeMouseEvent e)
{
}
public void nativeMouseReleased(NativeMouseEvent e)
{
}
public void nativeMouseMoved(NativeMouseEvent e)
{
}
public void nativeMouseDragged(NativeMouseEvent e)
{
}
public void nativeMouseWheelMoved(NativeMouseWheelEvent e)
{
}
public static void startListener()
{
try
{
GlobalScreen.registerNativeHook();
}
catch (NativeHookException ex)
{
System.err.println("Et problem oppsto.");
System.err.println(ex.getMessage());
System.exit(1);
}
Listener listener = new Listener();
GlobalScreen.getInstance().addNativeKeyListener( listener );
GlobalScreen.getInstance().addNativeMouseListener( listener );
GlobalScreen.getInstance().addNativeMouseMotionListener( listener );
GlobalScreen.getInstance().addNativeMouseWheelListener( listener );
}
}
My problem is that right after registering the key listeners in the Listener class the program terminates with the code '0'.
It used to work until I did something and now it just terminates upon start. I tried to start a thread just to keep the program alive, and that worked, but noone of the listeners worked.
Thank you in advance!
Update:
I tried with the exampleclass from https://code.google.com/p/jnativehook/wiki/examples but event that does not work anymore?!
the same problem as with the above problem. Both my classes ( the ones above ) and the example calsses used to work, but now they all just terminates after registering the listeners ( The main method in the example classes )
Is it my eclipse or anything that is wrong here?
Without running your code, my guess is that the jvm's "main" thread started the listeners but then didn't block, it exited the "main" method.
Your program runs and ends. It is over, finished and is done. So it "stops".
Starting a (new) thread would be the right way. But do not use a thread to "keep the program alive", use it for something useful. In your case, a thread could open a socket and listen on that socket for incoming messages (you are writing a chat client, right?). If a message comes in, the thread will handle it and response.
Or make a new thread out of your listener - instead of a method startListener, you could create a method called startListenerThread.
Your progamm flow would be:
start main method (the main thread)
the main thread starts the socket thread
the main thread starts the .... (what ever)
the main thread waits until all other threads have finished (it blocks)
Starting with Windows Vista, Microsoft made un/under-documented changes to the way SetWindowsHookEx() works. Basically they have set a upper limit on the number of hooks that can be used and they have also set processing time limits on each callback. There is no way to fix, detect or otherwise work around this new behavior. Please let me know how you managed to keep that many copes of the hook running and what version of the library you are using. Additional information on the problem can be found here.
Update:
I wanted to answer the original question about the inconsistencies in the way the application terminates after reaching the end of main. There were some issues in the way the native thread was attaching to the JVM prior to 1.2.0 RC1 that were causing part of the issue you were describing above. That native thread should now be attached as a user thread, opposed to a daemon thread, which will prevent the application from terminating as long as the native thread is registered. I believe this was the behavior you were originally expecting from the library.
I rebooted my computer and it worked again. My program does not properly shut down and gets stuck in memory as a Listener. It seems that the program only works until there are about 8 other of the same application in memory running. I do not understand how this happen, but after I fix my shutdown precedure everything should be fine again.

Java RMI with Callable

I have a server and several clients. The server should be able to delegate tasks to the clients so I tried to implement RMI. I followed this tutorial and everything is working fine if I use String as param- and/or return-value.
Now the server should send undefined tasks to the clients so I tried to use a Callable as param but the program crashed with a NotSerializableException. Since Callable doesn't implement the Serializeable interface thats the result I expected.
Now I found several sources that use Callable and Runnable as params and that confuses me. Is there any trick to get it to work? Or do i miss something important? Maybe theres a technology that fits better?
Resource1 S. 33
Resource2 s. 5
And heres my code:
// Client
public static void main(String[] args) throws InterruptedException {
App app = new App();
app.startClient();
Thread.sleep(20000);//just for test purpose
}
private void startClient() {
try {
// create on port 1099
Registry registry = LocateRegistry.createRegistry(1099);
// create a new service named myMessage
registry.rebind("calcClient", new CalculateRemoteImpl<String>());
} catch (RemoteException e) {
e.printStackTrace();
}
System.out.println("System is ready");
}
// RemoteInterface
public interface CalculateRemote<T> extends Remote {
public T hello(Callable<T> hello) throws RemoteException;
}
// RemoteInterfaceImpl
public class CalculateRemoteImpl<T> extends UnicastRemoteObject implements CalculateRemote<T> {
public T hello(Callable<T> hello) throws RemoteException {
return (T) ("Hello " + hello);// just print address of object
}
}
.
// Server
public static void main(String[] args) {
App app = new App();
app.doTest();
}
private void doTest() {
try {
// fire to localhost port 1099
Registry myRegistry = LocateRegistry.getRegistry("127.0.0.1", 1099);
// search for myMessage service
CalculateRemote<String> impl = (CalculateRemote<String>) myRegistry.lookup("calcClient");
// call server's method
System.out.println("Message: " + impl.hello(new Callable<String>() {
public String call() throws RemoteException, Exception {
return "hello";
}
}));
System.out.println("Message Sent");
} catch (NotBoundException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
}
// And the same RemoteInterface
public interface CalculateRemote<T> extends Remote {
public T hello(Callable<T> hello) throws RemoteException;
}
.
// stacktrace
java.rmi.MarshalException: error marshalling arguments; nested exception is:
java.io.NotSerializableException: de.fhb.rmicalcserver.App$1
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:156)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
at $Proxy0.hello(Unknown Source)
at de.fhb.rmicalcserver.App.doTest(App.java:30)
at de.fhb.rmicalcserver.App.main(App.java:18)
Caused by: java.io.NotSerializableException: de.fhb.rmicalcserver.App$1
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
at sun.rmi.server.UnicastRef.marshalValue(UnicastRef.java:292)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:151)
If you want to send objects to clients whose classes aren't deployed at the client you need to take a long look at the RMI codebase feature.

How to programmaticaly (java) obtain JBoss info and manage it?

Hi i want to obtain from java classes infos on JBoss like the status and the version and then manage him by starting/stopping/resatring him.
For the version i do this :
String fileSeparator = System.getProperty("file.separator");
String runJarFile = jbossHomeDir + fileSeparator + "bin" + fileSeparator + "run.jar";
System.out.println("JBOSSDIR est :" + runJarFile);
jarInputStream = new JarInputStream(new FileInputStream(runJarFile));
System.out.println("Pigmalion" + jarInputStream.getNextEntry().getName());
Manifest manifest = jarInputStream.getManifest();
Attributes attributes = manifest.getMainAttributes();
jbossVersion = attributes.getValue(Attributes.Name.SPECIFICATION_VERSION);
which works fine, now for the status, i saw some people doing it by checking the port, but isn't there another way of doing it ?
As for the start/stop/restart commands i saw this script
package com.sudipta.jboss.conf;
import org.jboss.Main;
public class JbossOperation {
public static Main ob;
static Class jbossMain;
static{
try {
jbossMain=Class.forName("org.jboss.Main");
ob = (Main)jbossMain.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
/**
* START JBOSS SERVER
* #return true if started successfully
*/
public static boolean startServer(){
boolean status=true;
String str[]={"-c","default"};
try {
ob.boot(str);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return status;
}
/**
* STOP JBOSS SERVER
* #return true if started successfully
*/
public static boolean stopServer(){
boolean status=true;
try {
ob.shutdown();
} catch (Throwable e) {
e.printStackTrace();
}
return status;
}
/**
* Main method
* #param args
*/
public static void main(String args[]){
System.out.println("---------------------Strating the server------------------");
startServer();
System.out.println("---------------------Stoping the server------------------");
stopServer();
System.out.println("---------------------SERVER STOPPED------------------");
}
}
I downloaded the jboss-system 4.0.2 jar and it tells me the shutdown method doesn't exist. Do i have to download other jboss jars ?
If you are looking for something more enterprisy (but still open source). You may want to use RHQ for it. It allows to run operations on managed resources and it can start/restart/stop JBoss server, deploy a war to it and far more. But the learning curve may be quite steep.
Have you considered to use JMX Console?. Moreover, if you really need to manage the server from a Java program you could write a JMX client that invoke specific server operations like shutdown. Additionaly, different kind of server information can be obtained this way. (ofcourse JMX wont be useful for start the server).

Returning String Array

I am having trouble with returning string array on a client and server environment. The result I getting is nothing when I compiled the client application.
server application
public String[] getFlight() throws Exception {
AvailableFlights todayFlight = new AvailableFlights();
List<Flight> flights_today = todayFlight.getFlightDetail();
List<String> flights = new ArrayList<String>();
try {
flights_today = this.unmarshal(new File("Flights.xml"));
for (Flight flight : flights_today) {
String flightDetail = flight.getJourney()
+ " " + flight.getAirline()
+ " "+ String.valueOf(flight.getConnections())
+ " "+ String.valueOf(flight.getCost())
+ " "+ flight.getDestination()
+ " "+ flight.getOrigin()
+ " "+ String.valueOf(flight.getSeats());
flights.add(flightDetail);
System.out.println(flightDetail);
}
} catch (Exception e) {
}
return (String[]) flights.toArray();
}
client java application
import org.me.kettravel.*;
public class JavaApplication5 {
public static void main(String[] args) {
try {
System.out.println(getFlight());
} catch (Throwable ex) {
}
}
private static java.util.List<java.lang.String> getFlight() throws Exception_Exception {
org.me.kettravel.ReadFlightService service = new org.me.kettravel.ReadFlightService();
org.me.kettravel.ReadFlight port = service.getReadFlightPort();
return port.getFlight();
}
Additionally I have tried a small experiment with "hello" like below on the server app and it worked fine, so I know that the web service is working fine but I just can't seem to pass/return the flights String array to the client app.
String i = "hello";
return i;
PS: When I try to run the server app with public static void main (String[] args) { constructor and without return, the app printed out the arraylist perfectly from unmarshalling xml convert it to arraylist and do system.out.print.
I would be grateful if anyone could shed some light as I am really stuck on this. Thanks.
04/01/2012 (19:16) - Adjustment has been made suggested by Genzer, the client app still not getting any response from server app.
04/01/2012 (23:24) - Adjustment has been made suggested by Bohemian can be seen below, the client app is now getting an error checking javax.xml.ws.soap.SOAPFaultException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
public static void main(String[] args) {
try {
Object obj = getFlight();
System.out.println(obj);
} catch (Throwable ex) {
System.out.println(ex);
}
}
06/01/2013 (16:20) - I have just addressed my mistake as the XML file was empty from tests to tests, however it is now have data in the xml file. I have just created a test class to see if readFlight returns anything to a class that it's in a same project/source package. Result is a success... really running out of ideas =/ as I have tested the web service by sending a simple hello string over to client app and worked no problem.
test class
public class test {
public static void main(String[] args) {
readFlight rF = new readFlight();
try {
System.out.println(rF.getFlight());
} catch (Throwable ex) {
System.out.println(ex);
}
}
}
Output from the test class: [London to Amsterdam KLM 1 200.0 Amsterdam London 100, London to Kuala Lumper Malaysia Airline 1 750.0 Kuala Lumper London 100, London to Manchester British Airway 1 50.0 Manchester London 56]
10/01/2013 (18:13) - PROBLEM SOLVED. You have to give full directory to the unmarshall file. Example: C:/Users/User/Documents/NetBeansProjects/WebService/booking.xml
The problem is that you have two different variables named flights. You populate one and return the other.
You could remove public static String[] flights and modify the method like this:
public List<String> getFlight() throws Exception {
Flight nextFlight = new Flight();
AvailableFlights todayFlight = new AvailableFlights();
List<Flight> flights_today = todayFlight.getFlightDetail();
// Since you you List for Flight, why not here
List<String> flights = new ArrayList<String>();
try {
flights_today = readFlight.unmarshal(new File("Flights.xml"));
for (Flight flight : flights_today) {
String flightDetail = flight.getJourney()
+ " " + flight.getAirline()
+ " "+ String.valueOf(flight.getConnections())
+ " "+ String.valueOf(flight.getCost())
+ " "+ flight.getDestination()
+ " "+ flight.getOrigin()
+ " "+ String.valueOf(flight.getSeats());
flights.add(flightDetail);
}
} catch (Exception e) {
}
return flights;
}
You have committed a "no no", which may be hiding the problem:
catch (Exception e) {
}
You should never (well, rarely) catch Exception. Especially when your catch block is empty.
There could be an unchecked exception, like NullPointerException, being thrown within your loop, but you wouldn't know.
Try removing the catch and leaving only soecific Exceptions (if any) that are declared to be thrown.
If one of the method is declared as throwing Exception, then at the very least, you should do this:
catch (Exception e) {
System.out.println(e);
}

GWT Server-side reflection

I am trying to use Reflection on the server side only of a GWT app. I have a basic example working in a non-GWT example which can be seen below.
package com.xyz.reflection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class EntryPoint {
/**
* #param args
*/
public static void main(String[] args) {
ClassLoader dynClassLoader = ClassLoader.getSystemClassLoader();
Class<?> dynClass = null;
try {
dynClass = dynClassLoader.loadClass("com.xyz.reflection.RunMe");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Object dynInstance = null;
try {
dynInstance = dynClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
Method dynMethod = null;
try {
try {
dynMethod = dynInstance.getClass().getMethod("returnSid",
new Class[] { PassMe.class });
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
String returnValue = (String) dynMethod.invoke(dynInstance,
new Object[] { new PassMe() });
System.out.println("Return Value: " + returnValue.toString());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
using the aptly named:
package com.xyz.reflection;
public class PassMe {
private String sid = "DEFAULT_SID";
public PassMe() {
this.sid = "INITIATED_SID";
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
}
and:
package com.xyz.reflection;
public class RunMe {
public String returnSid(PassMe s) {
return s.getSid();
}
}
This runs fine. When I try running this from a GWT server side class it doesn't work, and instead returns
java.lang.NoSuchMethodException: com.xyz.reflection.RunMe.returnSid(com.xyz.reflection.PassMe)
If I change the parameter to a String (instead of the 'PassMe' class) it works fine. Why does it not like passing my 'PassMe' class? I thought it might be an issue with serialization despite being 100% server code, but I haven't had any luck with this either.
Thanks in advance for any help anyone can give me with this.
In addition to finrod's solution, you can also change your class loader to something like:
ClassLoader dynClassLoader = PassMe.class.getClassLoader();
And you can use the PassMe.class style lookup again. The class used to find a loader doesn't seem to matter though. Just not the system loader.
Weird stuff. I wouldn't doubt if GWT is doing something weird with the class loader though.
Edit: Yep. GWT sets the system class loader to com.google.appengine.tools.development.IsolatedAppClassLoader in dev mode.
I think this could be related to Class loading - but it is just a hunch as I cannot experiment with it in context similar to yours.
Here are some suggestions to try:
You use:
ClassLoader dynClassLoader = ClassLoader.getSystemClassLoader();
dynClass = dynClassLoader.loadClass("com.xyz.reflection.RunMe");
To load the RunMe Class.
However to load the PassMe class you use:
PassMe.class
Try to load the PassMe Class through the dynClassLoader and use that instance in the getMethod() instead of the PassMe.class.
I wonder, do you need to use the dynClassLoader?
This is pretty much a shot in the dark, but does it help if you replace
dynMethod = dynInstance.getClass().getMethod("returnSid",
new Class[] { PassMe.class });
with
dynMethod = dynInstance.getClass().getMethod("returnSid", PassMe.class );
?
It doesn't make a difference outside of a GWT server, but it may exercise the container's VM differently.
Did you put your reflection file in the server side package?
For example:
org.myproject.client - your gwt client package (put here your java files that are able to be complied into java script NO REFLECTION)
org.myproject.server - put here any java files including reflection
org.myproject.shared - put here java classes that are able to be compiled into java script

Categories