Just when I thought I know how RMI works, it comes back and tell me I do not. The following situation:
I have given:
an interface: http://pastebin.com/KxXH1jQ9
an adress where the rmiregistry is runnung
The interface offers cleary 3 getter methods to gain informations about the object. I simply want to lookup the object call the three methods and print out theirs values:
However the following implementation ( http://pastebin.com/d4JS0Wai ) does not do the trick resulting in the following exception:
Exception in thread "main" java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.lang.ClassNotFoundException: Article
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at rmi.ArticleDisplayer.main(ArticleDisplayer.java:21)
Caused by: java.lang.ClassNotFoundException: Article
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
...
Also I don't know why I should need a SecurityManager anyway, as my machine is not executing the code. The code is executed on the machine running the rmiregistry. Anyway this is my policy file: http://pastebin.com/chGEqceA
This problem occurs because you should have the same Article class accessible by both the client and the source applications.
You can do a Jar with the common classes used by the 2 modules (client and server) and use it (I generally give the name "commons" to these type of packages).
Okay, the answer to the problem:
The implementation, as well as the interface are inside the default package. I wrote the program inside my own package: rmi
Also the interfaces I downloaded where in the package rmi. As a matter of fact rmi.Article != Article.
Related
Running into Exception caused during call to UnicastRemoteObject.exportObject().
javax.json.jar is on the classpath and is used in many other places in the application without any problems.
This part of the application worked fine until I added a method that returned a JsonValue to the remote object.
Any ideas?
java.rmi.ServerError: Error occurred in server thread; nested exception is:
java.lang.NoClassDefFoundError: javax/json/JsonValue
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:416)
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:556)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:811)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:670)
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:745)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:275)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:252)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:378)
at sun.rmi.registry.RegistryImpl_Stub.bind(Unknown Source)
NOTE:
I also tried running the rmiregistry with codebase pointed directly at the javax.json.jar but the exception remains
rmiregistry -J-Djava.rmi.server.codebase=file:///JarLibrary/javax.json.jar &
Running into Exception caused during call to UnicastRemoteObject.exportObject().
No you aren't. See the stack trace. It's happening in Registry.bind().
You need to run the server with the java.rmi.server.codebase property set, but a file:// codebase URL isn't going to work unless either all the clients are running in the server host, in which case you don't really need the codebase feature at all, or it points to a shared folder in a form that both the Registry and the clients can use. It's usually HTTP.
But I question whether you need the codebase feature at all. You just have to ensure that the relevant jar file is on the CLASSPATH of both the Registry and the clients. The simplest way to ensure that for the Registry is to use LocateRegistry.createRegistry() in the server JVM instead of the external rmiregistry program.
I'm also wondering why you're using JSON at all. RMI is built over Object Serialization. You don't need to add another serializer.
Hi I have RMI application and now I try to invoke some methods at server from my client. I have following code:
public static void main(final String[] args) {
try {
//Setting the security manager
System.setSecurityManager(new RMISecurityManager());
IndicatorsService server = (IndicatorsService) Naming
.lookup("rmi://localhost/" + IndicatorsService.SERVICE_NAME);
DataProvider provider = new OHLCProvider(server);
server.registerOHLCProvider(provider);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
server Is correctly loaded, but when I am trying to call server.registerOHLCProvider(provider); I get these errors:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: sk.xorty.client.providers.OHLCProvider (no security manager: RMI class loader disabled)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:336)
at sun.rmi.transport.Transport$1.run(Transport.java:159)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
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 sk.fri.statistics.service.impl.IndicatorsServiceImpl_Stub.registerOHLCProvider(Unknown Source)
at sk.fri.statistics.service.Client.main(Client.java:61)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: sk.xorty.client.providers.OHLCProvider (no security manager: RMI class loader disabled)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:296)
at sun.rmi.transport.Transport$1.run(Transport.java:159)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassNotFoundException: sk.xorty.client.providers.OHLCProvider (no security manager: RMI class loader disabled)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:375)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:165)
at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:620)
at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:247)
at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:197)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1574)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:306)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:290)
... 9 more
I have added my policy file as VM argument, here is how it looks like:
grant {
permission java.security.AllPermission;
}
It keeps saying something about disabled classloading, so I guess problem is somewhere there ...
Thanks!
Remote class loading can be tricky.
The original post doesn't include any information about the code base. It may be that the client's security configuration is correct, but it has no access to the remote code. The classes are loaded directly from the "code base" by the client. They are not presented to the client by the service over the RMI connection. The service merely references an external source for the classes.
The server should specify the system property java.rmi.server.codebase. The value must be a URL that is accessible to the client, from which the necessary classes can be loaded. If this is a file: URL, the file system must be accessible to the client.
And the other way around: If the server should be able to load classes from the client (like here), the client must set the code base property to a URL that is accessible to the server.
Every time you invoke a method on an RMI dynamic proxy, the MarshalInputStream (which extends ObjectInputStream to override resolveClass and resolveProxyClass) delegates to LoaderHandler to look in 3 places for the ClassLoader to use:
The ClassLoader of the proxy that is being invoked (technically, it uses a hack called latestUserDefinedLoader(): it walks up the stack, looking for the first method on the stack that is not part of JRE).
Thread-local contextClassLoader of the caller
Codebase ClassLoader if SecurityManager is enabled
If System property java.rmi.server.useCodebaseOnly=false, then the codebase ClassLoader uses URLs in the remote java.rmi.server.codebase. Note that the default value of useCodebaseOnly changed in JDK 7u21 so that remote codebase is not used anymore unless you change it!
Otherwise, the codebase ClassLoader uses URLs in the local java.rmi.server.codebase.
So there are a few possible reasons that you would get a ClassNotFoundException when invoking a Remote method:
If stack contains “no security manager: RMI class loader disabled”, then make sure to set a SecurityManager as described by others if you need remote class loading for both sides to get all the Remote interfaces and serializable classes.
If you are using remote class loading and it stopped working when you upgraded to JRE 7u21, then either set -Djava.rmi.server.useCodebaseOnly=true to match previous behavior, or set -Djava.rmi.server.codebase to a space-separated list of URLs on both the local and the remote sides. And make sure that computer can access those URLs.
If you are using a custom ClassLoader locally whose parent classloader defines some Remote interfaces, then make sure to call Thread.setContextClassLoader(ClassLoader) so that RMI will use that ClassLoader. (This was my problem: I had a SwingWorker that happened to be scheduled onto a worker thread that was created before the contextClassLoader was set on the EventDispatchThread). For example, A and C belong to your custom ClassLoader but B belongs to the parent ClassLoader, then when you call a.getB().getC(), the getB() call will use the custom classloader, but the getC() call will fail to find C in the latestUserDefinedClassLoader and will have to fall back to the contextClassLoader.
All of this is a cautionary tale on poor API design of ObjectInputStream. ObjectInputStream should have required you to pass a ClassLoader parameter, not try to find one haphazardly using latestUserDefinedLoader, contextClassLoader, and codebase.
I want to add something which may be helpful for some people, especially begginers.
I came here and searched for a solution for the above error, but being a beginner, I didn't know how to use security policies and specify the "java.rmi.server.codebase" attribute.
The simplest way to fix that error is to make sure that the classes of the objects to be sent over RMI are in the same path of packages.. In this way, both applications have the class in the same location relative to their main folder and the error will solve.
Example:
If you want to send an object of type MedicationDTO (which is serializable) from server to client, make sure that it is in the same package path.
In my case, in the server app, the object was in com.example.springdemo.dto and in the client app, it was in com.example.springdemo.service.dto.. The problem was that, using IntelliJ, because the service package had nothing in it, but an other package, their name was concatenated (service.dto) and I could not see that the path was not the same.
So, make sure that your classes have the same package path. (Solution for my case: MedicationDTO class has to be in both application in package: com.example.springdemo.dto.
I know this is not the best solution, it's just a 'little trick', but I would have been extremely happy to find this solution then, because it had saved me from a lot of wasted time to solve the problem.
I hope this will be helpful for those who want a quick fix to that error, because I think learning to use security managers and including codebase could be a little tricky and will take time.
You need the security manager at the server side, not only at the client side.
Without this, the server's RMI engine refuses to load classes from the client, as it can't guarantee that these won't do evil things on the server.
Do you need the RMI class loading at all? Couldn't the server already have the classes which the client tries to send?
I know my case is extremely special but maybe it helps others. I had the case that there were multiple applications on one server sharing the same registry with different paths of course. Wherever this registry is created (usually from the first application) the full classpath of all later applications must be specified in this first application. To sum it up:
Make sure policy is provided
Make sure classpath is full specified for all applications, clients and server
I know why it happens.
for example you start server in the project A,
but you use the Client in the project B to request this server,this is wrong.
So you should put the server and client in the same project.
This question already has answers here:
java.rmi.ServerException: RemoteException occurred in server thread (ClassNotFoundException)
(5 answers)
Closed 5 years ago.
I'm running the program here on 2 JVMs on diff physical machines. I get the error
RemoteException
java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.lang.ClassNotFoundException: CalculatorImpl_Stub (no security manager: RMI class loader disabled)
I've even tried running it on the same machine(unchanged program) and it works but it doesnt work on diff machines. Can someone pls help me out?
#beny23- Thanks but I still end up with this error:
RemoteException
java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.lang.ClassNotFoundException: CalculatorImpl_Stub
How can the client side have a copy of CalculatorImpl_stub?
I had this problem because I had different package names in client and server code:
package my.pkg;
// server side interface definition...
// ------------- //
package my.pkg.something;
// client side interface definition...
I changed the name of client-side package and set it as the name of server-side package:
package my.pkg;
// server side interface definition...
// ------------- //
package my.pkg; // renamed to the name of package in server-side .
// client side interface definition...
and the problem went away.
I had a working RMI Client and Server for my Java class. I decided to place these into their own packages rather than running as a default package.
After I placed them in their own Packages the java.rmi.UnmarshalException: error unmarshalling return; nested exception is: java.lang.ClassNotFoundException: error started happening on connection,.
I put the programs back into the default package and it all started working again.
I realize that there is probably a technical reason for this, but this worked for me!
It sounds like your not using a security manager:
Have you got a policy file (my.policy):
grant {
permission java.security.AllPermission;
};
and run your program using
java -Djava.security.manager -Djava.security.policy=/some/path/my.policy MyClass
There are three cases.
If you get the error when binding to the Registry, the Registry doesn't have access to that class on its classpath or via the codebase feature.
If you get the error when looking up the Registry, your client doesn't have access to that class on its classpath or via the codebase feature.
If you are using the codebase feature, that in turn can be caused by the Registry having access to that class on its classpath, which causes it not to use the codebase, which causes loss of the codebase annotation, so your client doesn't know to use the codebase for that class.
If you aren't using the codebase feature, ignore the previous paragraph ;-)
i solved it with rename package name. the server and client is in two different project , but rather with same package naming.
Hi I have RMI application and now I try to invoke some methods at server from my client. I have following code:
public static void main(final String[] args) {
try {
//Setting the security manager
System.setSecurityManager(new RMISecurityManager());
IndicatorsService server = (IndicatorsService) Naming
.lookup("rmi://localhost/" + IndicatorsService.SERVICE_NAME);
DataProvider provider = new OHLCProvider(server);
server.registerOHLCProvider(provider);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
server Is correctly loaded, but when I am trying to call server.registerOHLCProvider(provider); I get these errors:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: sk.xorty.client.providers.OHLCProvider (no security manager: RMI class loader disabled)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:336)
at sun.rmi.transport.Transport$1.run(Transport.java:159)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
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 sk.fri.statistics.service.impl.IndicatorsServiceImpl_Stub.registerOHLCProvider(Unknown Source)
at sk.fri.statistics.service.Client.main(Client.java:61)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: sk.xorty.client.providers.OHLCProvider (no security manager: RMI class loader disabled)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:296)
at sun.rmi.transport.Transport$1.run(Transport.java:159)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassNotFoundException: sk.xorty.client.providers.OHLCProvider (no security manager: RMI class loader disabled)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:375)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:165)
at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:620)
at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:247)
at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:197)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1574)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:306)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:290)
... 9 more
I have added my policy file as VM argument, here is how it looks like:
grant {
permission java.security.AllPermission;
}
It keeps saying something about disabled classloading, so I guess problem is somewhere there ...
Thanks!
Remote class loading can be tricky.
The original post doesn't include any information about the code base. It may be that the client's security configuration is correct, but it has no access to the remote code. The classes are loaded directly from the "code base" by the client. They are not presented to the client by the service over the RMI connection. The service merely references an external source for the classes.
The server should specify the system property java.rmi.server.codebase. The value must be a URL that is accessible to the client, from which the necessary classes can be loaded. If this is a file: URL, the file system must be accessible to the client.
And the other way around: If the server should be able to load classes from the client (like here), the client must set the code base property to a URL that is accessible to the server.
Every time you invoke a method on an RMI dynamic proxy, the MarshalInputStream (which extends ObjectInputStream to override resolveClass and resolveProxyClass) delegates to LoaderHandler to look in 3 places for the ClassLoader to use:
The ClassLoader of the proxy that is being invoked (technically, it uses a hack called latestUserDefinedLoader(): it walks up the stack, looking for the first method on the stack that is not part of JRE).
Thread-local contextClassLoader of the caller
Codebase ClassLoader if SecurityManager is enabled
If System property java.rmi.server.useCodebaseOnly=false, then the codebase ClassLoader uses URLs in the remote java.rmi.server.codebase. Note that the default value of useCodebaseOnly changed in JDK 7u21 so that remote codebase is not used anymore unless you change it!
Otherwise, the codebase ClassLoader uses URLs in the local java.rmi.server.codebase.
So there are a few possible reasons that you would get a ClassNotFoundException when invoking a Remote method:
If stack contains “no security manager: RMI class loader disabled”, then make sure to set a SecurityManager as described by others if you need remote class loading for both sides to get all the Remote interfaces and serializable classes.
If you are using remote class loading and it stopped working when you upgraded to JRE 7u21, then either set -Djava.rmi.server.useCodebaseOnly=true to match previous behavior, or set -Djava.rmi.server.codebase to a space-separated list of URLs on both the local and the remote sides. And make sure that computer can access those URLs.
If you are using a custom ClassLoader locally whose parent classloader defines some Remote interfaces, then make sure to call Thread.setContextClassLoader(ClassLoader) so that RMI will use that ClassLoader. (This was my problem: I had a SwingWorker that happened to be scheduled onto a worker thread that was created before the contextClassLoader was set on the EventDispatchThread). For example, A and C belong to your custom ClassLoader but B belongs to the parent ClassLoader, then when you call a.getB().getC(), the getB() call will use the custom classloader, but the getC() call will fail to find C in the latestUserDefinedClassLoader and will have to fall back to the contextClassLoader.
All of this is a cautionary tale on poor API design of ObjectInputStream. ObjectInputStream should have required you to pass a ClassLoader parameter, not try to find one haphazardly using latestUserDefinedLoader, contextClassLoader, and codebase.
I want to add something which may be helpful for some people, especially begginers.
I came here and searched for a solution for the above error, but being a beginner, I didn't know how to use security policies and specify the "java.rmi.server.codebase" attribute.
The simplest way to fix that error is to make sure that the classes of the objects to be sent over RMI are in the same path of packages.. In this way, both applications have the class in the same location relative to their main folder and the error will solve.
Example:
If you want to send an object of type MedicationDTO (which is serializable) from server to client, make sure that it is in the same package path.
In my case, in the server app, the object was in com.example.springdemo.dto and in the client app, it was in com.example.springdemo.service.dto.. The problem was that, using IntelliJ, because the service package had nothing in it, but an other package, their name was concatenated (service.dto) and I could not see that the path was not the same.
So, make sure that your classes have the same package path. (Solution for my case: MedicationDTO class has to be in both application in package: com.example.springdemo.dto.
I know this is not the best solution, it's just a 'little trick', but I would have been extremely happy to find this solution then, because it had saved me from a lot of wasted time to solve the problem.
I hope this will be helpful for those who want a quick fix to that error, because I think learning to use security managers and including codebase could be a little tricky and will take time.
You need the security manager at the server side, not only at the client side.
Without this, the server's RMI engine refuses to load classes from the client, as it can't guarantee that these won't do evil things on the server.
Do you need the RMI class loading at all? Couldn't the server already have the classes which the client tries to send?
I know my case is extremely special but maybe it helps others. I had the case that there were multiple applications on one server sharing the same registry with different paths of course. Wherever this registry is created (usually from the first application) the full classpath of all later applications must be specified in this first application. To sum it up:
Make sure policy is provided
Make sure classpath is full specified for all applications, clients and server
I know why it happens.
for example you start server in the project A,
but you use the Client in the project B to request this server,this is wrong.
So you should put the server and client in the same project.
I wrote a remote service MyremoteImpl.java and used following command after compiled it.
rmic MyRemoteImpl
I learned that this method suppose to create stub class and a skeleton class but I can only see the stub class, why is that?
The other problem I faced after run rmiregistry I started the service but it gives following error, I doubt I get this error as I'm missing skeleton class?
java.net.MalformedURLException: invalid URL String: Remote Hello
at java.rmi.Naming.parseURL(Unknown Source)
at java.rmi.Naming.rebind(Unknown Source)
at RMIservice.MyRemoteImpl.main(MyRemoteImpl.java:22)
Caused by: java.net.URISyntaxException: Illegal character in path at index 6: Remote Hello
at java.net.URI$Parser.fail(Unknown Source)
at java.net.URI$Parser.checkChars(Unknown Source)
at java.net.URI$Parser.parseHierarchical(Unknown Source)
at java.net.URI$Parser.parse(Unknown Source)
at java.net.URI.<init>(Unknown Source)
at java.rmi.Naming.intParseURL(Unknown Source)
... 3 more
Please help me to solve this, Thanx in advance!!!
Don't do this. You don't need it. Skeleton classes haven't been required since 1998.
From rmic 1.2 onwards, Java don't generate skeletion class any more. New JRMP protocol supported for RMI has got rid of the use of skeleton files.
A skeleton for a remote object is a JRMP protocol server-side entity that has a method that dispatches calls to the actual remote object implementation.