I try to launch this app using RMI client-server.
Firstly, I ran it and had the error "Connection refused to host: localhost".
After that I went go system32/drivers/etc/hosts and fix it, added line:
127.0.0.1 localhost
It wasn't led me to problem solution.
Then I looked up same questions in stackoverflow about how to fix this problem, then solved it with (ran in cmd):
start rmiregistry
So, rmiregistry ran and i had got a new error - NotBoundException (but I could fix "Connection refusal" problem).
servicebrowser.java:
package servicebrowser;
import java.awt.*;
import javax.swing.*;
import java.rmi.*;
import java.awt.event.*;
public class ServiceBrowser {
JPanel mainPanel;
JComboBox serviceList;
ServiceServer server;
public void buildGUI() {
Object[] services = getServicesList();
}
Object[] getServicesList() {
Object obj = null;
Object[] services = null;
try {
obj = Naming.lookup("rmi://127.0.0.1/ServiceServer");
}
catch (Exception ex) { ex.printStackTrace(); }
server = (ServiceServer) obj;
try {
services = server.getServiceList();
}
catch (Exception ex) { ex.printStackTrace(); }
return services;
}
class MyListListener implements ActionListener {
public void actionPerformed(ActionEvent ev) {
Object selection = serviceList.getSelectedItem();
loadService(selection);
}
}
public static void main(String[] args) {
new ServiceBrowser().buildGUI();
}
}
class ServiceServerImpl:
import java.rmi.*;
import java.util.*;
import java.rmi.server.*;
public class ServiceServerImpl extends UnicastRemoteObject
implements ServiceServer {
HashMap serviceList;
public ServiceServerImpl() throws RemoteException {
setUpServices();
}
private void setUpServices() {
serviceList = new HashMap();
}
public Object[] getServiceList() {
System.out.println("in remote");
return serviceList.keySet().toArray();
}
public Service getService(Object serviceKey) throws RemoteException {
Service theService = (Service) serviceList.get(serviceKey);
return theService;
}
public static void main (String[] args) {
try {
Naming.rebind("ServiceServer", new ServiceServerImpl());
}
catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("Remote service is running");
}
}
What is wrong with it? I turned off firewall too, certaintly.
Thanks a lot!
I solved my problem right this way.
Firstly, I edited classes servicebrowser, ServiceServerImpl.
class servicebrowser:
Before:
try {
obj = Naming.lookup("rmi://127.0.0.1/ServiceServer");
}
Now (plus I added import java.rmi.registry.LocateRegistry, import java.rmi.registry.Registry in top part of code):
try {
Registry registry = LocateRegistry.getRegistry("127.0.0.1", 10001);
obj = registry.lookup("ServiceServer");
}
class ServiceServerImpl:
Before:
try {
Naming.rebind("ServiceServer", new ServiceServerImpl());
}
Now (like a previous class I added import classes in top part of code):
try {
Registry registry = LocateRegistry.createRegistry(10001);
registry.bind("ServiceServer", new ServiceServerImpl());
}
Secondly, I try to ran project (F6) in Netbeans, where servicebrowser marked as main class. It was refusal connection again. After that I only ran class ServiceServerImpl (Shift + F6) then ran entire projecе. So, it works.
P.S. I didn't use cmd and try to
"start rmiregistry"
because the app works without it.
Related
I am using IntelliJ as my IDE and the code below runs alright if they are in the same src folder. However, what I want is to call the sayHello() method in another project. Is that possible? I thought this is possible since this is what RMI enables, but am I wrong?
I tried to create another project that contains a Main java class and has the same code as the Client Test Drive below, hoping to call the sayHello() method by utilizing Naming.lookup() but it doesn't work! If I try to run it, I was given a java.rmi.UnmarshalException: error unmarshalling return; exception. What am I missing?
How can I call the sayHello() method "remotely"?
Remote Interface:
package Remote;
import java.rmi.*;
public interface HelloRemote extends Remote {
String sayHello() throws RemoteException;
}
Remote Implementation
package Remote;
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
public class HelloRemoteImpl extends UnicastRemoteObject implements HelloRemote{
public HelloRemoteImpl() throws RemoteException {};
#Override
public String sayHello() throws RemoteException {
return "Server says, \"Hello!\"";
}
public static void main(String[] args) {
try {
// 2.3 register the service
HelloRemote service = new HelloRemoteImpl();
final int PORT = 1888;
Registry registry = LocateRegistry.createRegistry(PORT);
registry.rebind("hello", service);
System.out.println("Service running on PORT: " + PORT);
} catch(Exception e) {
e.printStackTrace();
}
}
}
Client Test Drive
package Remote;
import java.rmi.Naming;
public class SayHelloTest {
public static void main(String[] args) {
try {
HelloRemote service = (HelloRemote) Naming.lookup("rmi://127.0.0.1:1888/hello");
String helloStr = service.sayHello();
System.out.println(helloStr);
} catch (Exception e) {
e.printStackTrace();
}
}
}
I am trying to register a bukkit Command on the other Command.
So I want to make "/command1" to register "/command2" so command 2 only can execute after I executed command 1.
I tried for like 10 hours by now to do that, at the moment I am able to register a command without making it into the plugin.yml and that works, just the second command does not get registered.
Main class:
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandMap;
import org.bukkit.plugin.SimplePluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import java.lang.reflect.Field;
public class Main extends JavaPlugin {
#Getter
CommandMap commandMap;
#Override
public void onEnable() {
loadCommandMap();
this.commandMap.register("command1", new FirstCommand(this));
}
private void loadCommandMap() {
try {
if (Bukkit.getPluginManager() instanceof SimplePluginManager) {
Field f = SimplePluginManager.class.getDeclaredField("commandMap");
f.setAccessible(true);
this.commandMap = (CommandMap) f.get(Bukkit.getPluginManager());
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
FirstCommand:
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
public class FirstCommand extends Command {
private Main plugin;
public FirstCommand(Main plugin) {
super("command1");
this.plugin = plugin;
}
#Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
plugin.getCommandMap().register("command2", new SecondCommand());
sender.sendMessage("Command 1.");
return true;
}
}
Second Command:
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
public class SecondCommand extends Command {
public SecondCommand() {
super("command2");
}
#Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
sender.sendMessage("Command 2");
return true;
}
}
I really hope someone knows why the first command gets registered but the second one does not.
You could try to not register them at runtime, but enable them at runtime.
You can use global, static variables (for example in the main class of your app), e.g.
// in your class "Main"
public static boolean isCommand2Enabled = false;
and when command1 is called, you set it to true
Main.isCommand2Enabled = true;
Your command2 must now only check whether it has already been activated and can be executed:
if(!Main.isCommand2Enabled) {
// I am not activated yet and must return
return false;
}
But I am not quite sure if you might try to define the name of command2 first when command1 is executed (variable command name). You should then maybe use a fixed command and only make the corresponding argument variable.
I don't really understand what you are talking about, but I think this may help you...
Bukkit Tutorial - Registering Commands At Runtime
I am learning RMI concepts and had built a simple program taking reference from head first java. All Went fine the first time i ran the code through command prompt.
the next time I ran code the command:
rmiregistry
took too long to load and nothing happened.
I even tried the solution in this thread but nothing happend.
need help to run RMI Registry
also when i run my server and client file i get this error:
Exception: java.rmi.ConnectException: Connection refused to host: 192.168.1.105; nested exception is:
java.net.ConnectException: Connection refused: connect
My Source Code:
myremote.java
import java.rmi.*;
public interface myremote extends Remote
{
public String sayhello() throws RemoteException;
}
Server.java
import java.rmi.*;
import java.rmi.server.*;
public class Server extends UnicastRemoteObject implements myremote
{
public Server() throws RemoteException{}
public String sayhello()
{
return("Server says hi");
}
public static void main(String args[])
{
try
{
myremote S = new Server();
Naming.rebind("remotehello",S);
}
catch(Exception E)
{
System.out.println("Exception: "+E);
}
}
}
client.java
import java.rmi.*;
public class client
{
public static void main(String[] args)
{
client c = new client();
c.go();
}
public void go()
{
try
{
myremote S=(myremote) Naming.lookup("rmi://127.0.0.1/remotehello");
System.out.println("Output:"+S.sayhello());
}
catch(Exception E)
{
System.out.println("Exception: "+ E);
}
}
}
Can't run RMI registry on my system
You've provided no evidence of that.
took too long to load
I don't know what this means. Evidence?
nothing happened.
Nothing is supposed to happen. The RMI registry doesn't print anything. It just sits there.
Run it and try again. You'll be surprised.
I would like to access an existing RMI server. I do not have access to its source code, so I would like to set up a client that calls an existing service in the RMI Server.
What is the best way to create a client to invoke a particular method and can RMI be converted to a webservice?
Below is the class I have created:
package server;
import com.SerialService;
import java.rmi.Naming;
public class NewClass {
public static void main(String args[]) {
//SerialService obj = null;
try {
SerialService obj = (SerialService) Naming.lookup("//localhost:8083/");
System.out.println(obj.getSerial());
} catch (Exception e) {
e.printStackTrace();
}
}
}
You will need to get the RMI services client stub so you can call/compile against. You would still need to know the port that the service is listening on.
import java.rmi.Naming;
public class RmiClient {
public static void main(String args[]) throws Exception {
RmiServerIntf obj = (RmiServerIntf)Naming.lookup("//localhost/RmiServer");
System.out.println(obj.getMessage());
}
}
I was wondering if it is possible to check whether there is an instance of an object(my gui) open in Java and if so how I would be able to find it?
You can use following code if this question is for swing window like JFrame or JDialog,
java.awt.Window win[] = java.awt.Window.getWindows();
for(int i=0;i<win.length;i++){
if (win[i].getName().equals("YourWindowName"))
isOpen = true;
break;
}
For this ypu need to give name to your JFrame and if that matches with open windows it will set true and return.
I used RMI to solve the same problem. My application creates Registry and places a lock object there after start. If lock object is already there at that time then it sends message via RMI to existing application and terminates. The sent message triggers existing application to move its window on top. Here is the code
public static void main(String[] args) {
RmiManager rmiManager = new RmiManager();
rmiManager.createRmiRegistry();
if(rmiManager.isAlreadyRunning()) {
logger.error("Another application instance is running! Exit");
System.exit(0);
return;
}
rmiManager.registerApplication();
}
RmiManager.java which is actually responsible for all the stuff
package myapp;
import java.rmi.AccessException;
import java.rmi.AlreadyBoundException;
import java.io.File;
import java.io.IOException;
import java.rmi.registry.LocateRegistry;
import java.rmi.NotBoundException;
import java.rmi.registry.Registry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import org.apache.log4j.Logger;
public class RmiManager {
private static final String LOCK_OBJECT_NAME = "myapp";
private static final Logger logger = Logger.getLogger(RmiManager.class);
public void createRmiRegistry() {
try {
logger.debug("Creating RMI registry...");
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
logger.debug("RMI registry was created");
} catch (RemoteException e) {
logger.debug("RMI registry is already created");
}
}
public boolean isAlreadyRunning() {
try {
logger.debug("Checking if application is already running. Looking for RMI registry...");
Registry registry = LocateRegistry.getRegistry();
logger.debug("RMI registry obtained. Looking for RmiListener: " + LOCK_OBJECT_NAME + "...");
try {
IRmiListener rmiListener = (IRmiListener) registry.lookup(LOCK_OBJECT_NAME);
logger.debug("RmiListener got. Checking...");
boolean isAlreadyRunning = rmiListener.isAlreadyRunning();
logger.debug("IsAlreadyRunning result: " + isAlreadyRunning);
return isAlreadyRunning;
} catch (AccessException e) {
logger.error("Error accessing RMI registry!", e);
return false;
} catch (NotBoundException e) {
logger.debug("RMI listener wasn't found. There are no other application instances running");
return false;
}
} catch (RemoteException e) {
logger.error("RemoteException!", e);
return false;
}
}
public void registerApplication() {
try {
logger.debug("Registering application...");
RmiListenerImpl rmiListenerImpl = new RmiListenerImpl();
logger.debug("Exporting RmiListener object...");
IRmiListener rmiListener = (IRmiListener) UnicastRemoteObject.exportObject(rmiListenerImpl, Registry.REGISTRY_PORT);
logger.debug("RmiListener object was exported. Looking for RMI registry...");
Registry registry = LocateRegistry.getRegistry();
logger.debug("RMI registry found");
try {
logger.debug("Binding RmiListener to " + LOCK_OBJECT_NAME + "...");
registry.bind(LOCK_OBJECT_NAME, rmiListener);
logger.debug("RmiListener binding was done. Application registration complete.");
} catch (AccessException e) {
logger.error("AccessException!", e);
} catch (AlreadyBoundException e) {
logger.error("RmiListener object is already bind", e);
}
} catch (RemoteException e) {
logger.error("RemoteException!", e);
}
}
}
IRmiListener.java
package myapp;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface IRmiListener extends Remote {
boolean isAlreadyRunning() throws RemoteException;
}
RmiListenerImpl.java
package myapp;
import java.rmi.RemoteException;
import org.apache.log4j.Logger;
public class RmiListenerImpl implements IRmiListener {
private static final Logger logger = Logger.getLogger( RmiListenerImpl.class );
#Override
public boolean isAlreadyRunning() throws RemoteException {
// here I notify my GUI class to pop up the window
return true;
}
}
It can be more simple I think.
Assuming that by "open UI objects" you mean Swing dialogs and frames, it is better to design the application in a way that would remove the need to look for open instances all together.
This can be achieved by providing a factory that would produce application dialogs and frames instead of using something like new JFrame. This factory would register the produced instances internally and would serve as a single point of reference for all "open UI objects".
Although, be careful when implementing such solution as every registered object would have one additional reference preventing GC from collecting the allocated memory as intended. Please used weak references (weak reference map) for caching. A good blog post about different kinds of Java references can be found here.
This way if you need to find an open UI object, simply request your factory to provide a list of open instances.