I am trying to run the rmi tutorial on oracles' website. I am able to run the server, but I receive an error running the client. The error I receive when try to run the cleint is a noNotBoundException exception. How do I fix this error?
Below is the code and exception
Exception
Client exception: java.rmi.NotBoundException: Hello
java.rmi.NotBoundException: Hello
at sun.rmi.registry.RegistryImpl.lookup(RegistryImpl.java:166)
at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:411)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:272)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
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 sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at example.hello.Client.main(Client.java:52)
Server
package example.hello;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class Server implements Hello {
public Server() {}
public String sayHello() {
return "Hello, world!";
}
public static void main(String args[]) {
try {
Server obj = new Server();
Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);
// Bind the remote object's stub in the registry
Registry registry = LocateRegistry.getRegistry();
registry.bind("Hello", stub);
System.err.println("Server ready");
} catch (Exception e) {
System.err.println("Server exception: " + e.toString());
e.printStackTrace();
}
}
}
Client
package example.hello;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
private Client() {}
public static void main(String[] args) {
String host = (args.length < 1) ? null : args[0];
try {
Registry registry = LocateRegistry.getRegistry(host);
Hello stub = (Hello) registry.lookup("Hello");
String response = stub.sayHello();
System.out.println("response: " + response);
} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
Interface
package example.hello;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Hello extends Remote {
String sayHello() throws RemoteException;
}
You need to launch the [RMI] registry. Method getRegistry() does not launch the registry. Method createRegistry(int) launches the registry. You need to change this line in your class Server
Registry registry = LocateRegistry.getRegistry();
to this
Registry registry = LocateRegistry.createRegistry(1099);
Note that 1099 is the default port used by RMI.
Related
we are trying to get RMI working over the Internet. What we tried:
Port forwarding (1099-1100) on Client and Serverside.
shut down firewall in windows and router
tried it with tunngle (www.tunngle.net/)
our RMI Interface:
import java.rmi.RemoteException;
public interface RMIInterface extends java.rmi.Remote {
public void helloWorld(int i) throws RemoteException;
}
our RMI Server Implementation:
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class RMIServerTest extends UnicastRemoteObject implements RMIInterface {
public RMIServerTest() throws RemoteException {
}
#Override
public void helloWorld(int i) throws RemoteException {
for (int j = 0; j < i; j++) {
System.out.println("Hello World");
}
}
public static void main(String[] args) {
try {
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
}
catch (RemoteException ex) {
System.out.println(ex.getMessage());
}
try {
Naming.rebind("Server", new RMIServerTest());
} catch (MalformedURLException ex) {
System.out.println(ex.getMessage());
} catch (RemoteException ex) {
System.out.println(ex.getMessage());
}
}
}
and our Client:
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
public class RMIClient {
public static void main(String[] args) throws RemoteException, NotBoundException,MalformedURLException {
try {
RMIInterface serverObject = (RMIInterface) Naming.lookup("//externalServerAdress/Server");
serverObject.helloWorld(10);
}
catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
We're still getting this Error:
Connection refused to host: 192.168.0.13; nested exception is:
java.net.ConnectException: Connection timed out: connect
192.168.0.13 is the local IP-adress of the Server behind his router. We connect on client with the external IP of the router. like "2.246.133.155" = externalServerAdress.
So we have a connection. We connect over the external IP adress of the server (WAN IP) and error shows, it gets the local IP-adress of the server, but still refuse connection.
thx for any hint.
Connection refused to host: 192.168.0.13
That's not an Internet address. It is a private address that only exists behind your router. You need to use your public IP address, and arrange port forwarding via your router.
So im using Smack to run my chat bot for league of legends, however I can't even get the bot to show up because of a missing class error that I can't seem to figure out. Code and error below, Thanks for any help, -Nick
Also: yes, this code was taken from an example because when I tried it myself I still got the same error.
package com.nickparks.bot;
import java.util.*;
import java.io.*;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
public class JabberSmackAPI implements MessageListener{
XMPPConnection connection;
public void login(String userName, String password) throws XMPPException
{
ConnectionConfiguration config = new ConnectionConfiguration("chat.na1.lol.riotgames.com",5223);
connection = new XMPPTCPConnection(config);
try {
connection.connect();
connection.login(userName, password, "xiff");
} catch (SmackException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void displayBuddyList()
{
Roster roster = connection.getRoster();
Collection<RosterEntry> entries = roster.getEntries();
System.out.println("\n\n" + entries.size() + " buddy(ies):");
for(RosterEntry r:entries)
{
System.out.println(r.getUser());
}
}
public void disconnect()
{
try {
connection.disconnect();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
}
public void processMessage(Chat chat, Message message)
{
if(message.getType() == Message.Type.chat)
System.out.println(chat.getParticipant() + " says: " + message.getBody());
}
public static void main(String args[]) throws XMPPException, IOException
{
// declare variables
JabberSmackAPI c = new JabberSmackAPI();
// Enter your login information here
c.login("bot", "Password");
c.displayBuddyList();
System.out.println("-----");
System.out.println("Who do you want to talk to? - Type contacts full email address:");
String talkTo = br.readLine();
System.out.println("-----");
System.out.println("All messages will be sent to " + talkTo);
System.out.println("Enter your message in the console:");
System.out.println("-----\n");
while( !(msg=br.readLine()).equals("bye"))
{
System.out.println("test");
}
c.disconnect();
System.exit(0);
}
}
And here's the error I get:
Exception in thread "main" java.lang.NoClassDefFoundError: org/xmlpull/v1/XmlPullParserFactory at org.jivesoftware.smack.SmackConfiguration.processConfigFile(SmackConfiguration.java:321)
atorg.jivesoftware.smack.SmackConfiguration.processConfigFile(SmackConfiguration.java:316)
at org.jivesoftware.smack.SmackConfiguration.<clinit>(SmackConfiguration.java:148)
at org.jivesoftware.smack.ConnectionConfiguration.<init>(ConnectionConfiguration.java:65)
at com.nickparks.bot.JabberSmackAPI.login(JabberSmackAPI.java:16)
at com.nickparks.bot.JabberSmackAPI.main(JabberSmackAPI.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
atsun.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:120)
Caused by: java.lang.ClassNotFoundException: org.xmlpull.v1.XmlPullParserFactory
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 11 more
You need to have XPP3 (XML Pull Parser 3) in your classpath. Smack 4 does no longer bundle it (unlike Smack 3).
I also recommend using a build system with dependency resolution like maven or gradle, which would automatically fetch the required dependencies.
I was trying to run the Hello World RMI example from the Oracle page, but I keep getting errors.
the error I keep getting is
Server exception: java.rmi.NoSuchObjectException: no such object in
table java.rmi.NoSuchObjectException: no such object in table 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) at
example.hello.Server.main(Server.java:26)
Here is the code as taken directly from the site that I used:
The Hello Interface:
package example.hello;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Hello extends Remote {
String sayHello() throws RemoteException;
}
This is what my server class:
package example.hello;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class Server implements Hello {
public Server() {}
public String sayHello() {
return "Hello, world!";
}
public static void main(String args[]) {
try {
Server obj = new Server();
Hello stub = (Hello) UnicastRemoteObject.exportObject(obj,0);
// Bind the remote object's stub in the registry
Registry registry = LocateRegistry.getRegistry("localhost");
registry.bind("Hello", stub);
System.err.println("Server ready");
} catch (Exception e) {
System.err.println("Server exception: " + e.toString());
e.printStackTrace();
}
}
}
Client code:
package example.hello;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
private Client() {}
public static void main(String[] args) {
String host = "localhost";
try {
Registry registry = LocateRegistry.getRegistry(host);
Hello stub = (Hello) registry.lookup("Hello");
String response = stub.sayHello();
System.out.println("response: " + response);
} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
Any feedback is greatly appreciated!
The Registry isn't running. Either start the rmiregistry tool, or change getRegistry() to createRegistry().
It's curious, as some JVM must have been listening on port 1099, but not with a Registry running in it. Normally no Registry causes a java.rmi.ConnectException.
I think your interface method should have public modifier
I want to build a RMI server, I tried like this
package first_project;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
public class Server extends UnicastRemoteObject implements ServerInterface {
// list for know users
protected ArrayList<ClientInterface> clients = new ArrayList<ClientInterface>();
public Server() throws RemoteException {}
//logged in clients get a notification that a new user has joined the chat
// remote reference to the new client is added to the ArrayList.
public void login(ClientInterface client, String nickname) throws RemoteException {
broadcastMessage("--> " + nickname + " is entering the chatroom", "");
clients.add(client);
}
// used for broadcasting an incoming message
// and the nickname of its sender to all currently logged in clients .
//remote call of the method getMessage which is
public void broadcastMessage(String message, String nickname) throws RemoteException {
for (int i = 0; i < clients.size(); i++) {
ClientInterface c = clients.get(i);
try {
c.getMessage(message, nickname);
} catch (RemoteException e) {
logout(c);
i = i - 1;
} }}
//remove user
public void logout(ClientInterface client) {
clients.remove(client);
}
public static void main(String[] args) {
try {
Naming.rebind("Server", new Server());
System.out.println("Server is ready");
} catch (Exception e) {
e.printStackTrace();
}
}
}
but i dont know why I got this exception:
java.rmi.ConnectException: Connection refused to host: 192.168.1.3; nested exception is:
java.net.ConnectException: Connection refused: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:601)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:198)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:184)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:322)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at java.rmi.Naming.rebind(Naming.java:160)
at first_project.Server.main(Server.java:47)
Caused by: java.net.ConnectException: Connection refused: connect
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:366)
at java.net.Socket.connect(Socket.java:519)
at java.net.Socket.connect(Socket.java:469)
at java.net.Socket.<init>(Socket.java:366)
at java.net.Socket.<init>(Socket.java:180)
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:595)
... 6 more
what am I doing wrong please?
thanks in advance
Have u started the registry. Try it after starting the registry
start rmiregistry for windows
rmiregistry & for Linux/Unix
I've been building an RMI application over the past week and I've hit a roadblock that no amount of googling can seem to help with.
The following code is used to send an object from the server to the client via RMI:
Server code:
import rocks.Rock;
import rocks.squareRock;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class Server extends UnicastRemoteObject
implements RemInterface {
public Server() throws RemoteException {
super();
}
public static void main(String argv[]) {
try {
Server serv = new Server();
Naming.rebind("RockServer", serv);
} catch (Throwable t) {
t.printStackTrace();
}
}
public Rock getRock() {
return new squareRock();
}
}
Client code:
import rocks.Rock;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
public class Client {
RemInterface reminterface = null;
public Client() {
String strName = "rmi://127.0.0.1/RockServer";
try {
reminterface = (RemInterface) Naming.lookup(strName);
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
public Rock loadRock() {
try {
return reminterface.getRock();
} catch (Throwable t) {
return null;
}
}
}
Interface:
public interface RemInterface {
public Rock getRock() throws RemoteException;
}
In this situation:
The "Rock" class is available in both the Client and Server classpath.
The "Rock" class implements serializable.
The "squareRock" extends class rock and is only available in the server's classpath.
The error I get when trying to call a method using a Rock from loadRock() on the client is as follows:
STDERR: java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.lang.ClassNotFoundException: SquareRock
Any help would be appreciated.
You are returning an object of Type rocks.squareRock from the Server. During the de-serialization process at the client, this class will be required in order to create an instance of this class to represent the response from the server. As you've already indicated that the class is available only in the server's classpath, the failure to locate and load the said class causes the exception.
The resolution will be to make the rocks.squareRock class available in the client as well.