java.rmi.NoSuchObjectException: no such object exception - java

There have been acouple of questions about this already, but their answers suggest that the exported object has been GC'd on the server side and that is cousing the problems. However it seems like that this is not the issue here.
Mentioned exception is thrown only on single machine:
PRETTY_NAME="Debian GNU/Linux 8 (jessie)"
NAME="Debian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
With java:
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
This happend on the same machine with OpenJDK 7something as well.
According to other answers I am supposed to keep a strong reference to handling objects. I am doing it now, so what more can be done?
The same code works on windows as well as on a different remote linux machine with java 7.
Any ideas why?
I have implemented some finalizers to the connected classes, but none of them are called.
As suggested I am using static references. As for me there is no way get exported object GC enligible. Exception is thrown on remote method invocation right after object lookup.
Piece of class
public class Client{
//some fields
private final int RMI_PORT;
private static SearchTestServiceImpl searchTestService;
private static Remote stub;
private Registry registry;
//and starting service
public void startService() throws RemoteException {
createRegistry();
searchTestService = new SearchTestServiceImpl(name);
stub = UnicastRemoteObject.exportObject(searchTestService, RMI_PORT + 1);
registry.rebind(SearchTestService.class.getName(), stub);
log.info("Binding {} to port {}", SearchTestService.class.getName(), RMI_PORT + 1);
}
private void createRegistry() throws RemoteException {
log.info("Starting RMI registry on port {}", RMI_PORT);
registry = LocateRegistry.createRegistry(RMI_PORT);
}
(...)
}
And bootstrapping code
public class Bootstrap {
private Logger log = LoggerFactory.getLogger(Bootstrap.class);
private static Client c;
public static void main(String[] args) throws NumberFormatException,
// some preparations
c = new Client(Integer.valueOf(port), name);
c.startService();
System.gc();
System.runFinalization();
synchronized (c) {
c.wait();
}
}
}
and stacktrace
java.rmi.NoSuchObjectException: no such object in table
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source) ~[na:1.7.0_65]
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source) ~[na:1.7.0_65]
at sun.rmi.server.UnicastRef.invoke(Unknown Source) ~[na:1.7.0_65]
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source) ~[na:1.7.0_65]
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source) ~[na:1.7.0_65]
at com.sun.proxy.$Proxy0.getName(Unknown Source) ~[na:na]
at call to a method of remote lookedup object #getName in this example.
Requested piece of code - lookup and call that throws exception
//somewhere
SearchTestService c = getClient(address); // this returns nice stub
String name = c.getName(); // this is throwing exception
private SearchTestService getClient(String string) throws NumberFormatException, RemoteException, NotBoundException {
String[] parts = string.split(":");
Registry registry = LocateRegistry.getRegistry(parts[0], Integer.parseInt(parts[1]));
SearchTestService client = (SearchTestService) registry.lookup(SearchTestService.class.getName());
return (SearchTestService) client;
}
Console output after running "listening" client side code (with RMI registry)
10:17:55.915 [main] INFO pl.breeze.searchtest.client.Client - Starting RMI registry on port 12097
10:17:55.936 [main] INFO p.b.s.client.SearchTestServiceImpl - Test agent Breeze Dev staging is up and running
10:17:55.952 [main] INFO pl.breeze.searchtest.client.Client - Binding pl.choina.searchtest.remote.SearchTestService to port 12098
And this waits untill manuall shutdown - tested.

NoSuchObjectException
Javadoc:
A NoSuchObjectException is thrown if an attempt is made to invoke a method on an object that no longer exists in the remote virtual machine.
This means that the remote object referred to by the stub you are calling methods on has been unexported, i.e. the stub is 'stale'. The only way that can happen is by unexporting the object, either manually or as a result of GC.
As suggested I am using static references.
No you're not. You need to make the Registry reference static. Otherwise you just form a cycle between Client and Registry that can be garbage-collected all at once.
Why you're calling your server Client is another mystery.
EDIT A few comments:
stub = UnicastRemoteObject.exportObject(searchTestService, RMI_PORT + 1);
There's no need to use a second port here. Just re-use the Registry port.
log.info("Binding {} to port {}", SearchTestService.class.getName(), RMI_PORT + 1);
This is misleading. You've already done both, but what you have done is:
Exported the object on the port, and
Bound the object to a name
in two separate steps.
System.gc();
System.runFinalization();
Strange things to be doing here, or indeed anywhere.
synchronized (c) {
c.wait();
}
This isn't reliable. You don't really need anything here, as RMI should keep the JVM open as long as it has exported remote objects, but you could do what the Registry does:
while (true)
{
Thread.sleep(Integer.MAX_VALUE);
}
with the appropriate exception handling.
I can't reproduce your problem, but then I'm on Windows 7.

Related

How to avoid DB2 driver Classloader Memory leak on Tomcat application .war file redeployment

IBM's well supported JDBC driver creates a memory leak in combination with Tomcat's well supported connection pool.
Please refer to Classloader memory leak on Tomcat application .war file redeployment.
java.lang.IllegalStateException: Illegal access: this web application instance has been stopped already. Could not load [DB2JccConfiguration.properties]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading(WebappClassLoaderBase.java:1327)
at org.apache.catalina.loader.WebappClassLoaderBase.getResource(WebappClassLoaderBase.java:1023)
at com.ibm.db2.jcc.am.ud.run(Unknown Source)
at java.security.AccessController.doPrivileged(AccessController.java:285)
at com.ibm.db2.jcc.am.GlobalProperties.a(Unknown Source)
at com.ibm.db2.jcc.am.GlobalProperties.d(Unknown Source)
at com.ibm.db2.jcc.am.mq.run(Unknown Source)
at java.util.TimerThread.mainLoop(Timer.java:567)
at java.util.TimerThread.run(Timer.java:517)
I do not understand the suggested solution as it is in conflict with the most recommended practice of including the driver jar in the Tomcat lib directory.
We need shared deployment and re-deployment without Tomcat re-start. Please share your solution here if you have experience with this software combination and the described issue.
For driver version 4.22.29, I'm currently using this code in a ServletContextListener:
#Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
// This fixes the JDBC driver not unloading corectly on a context reload for DB2 JDBC 4.22.29
try {
logger.debug("Trying to stop the timer");
new com.ibm.db2.jcc.am.iq() {
// instance initializer to execute the fix when the anonymous class is instantiated, i.e. now
{
if (a != null) {
a.cancel();
} else {
logger.debug("Timer is null, skipped");
}
}
};
logger.debug("Stopped the timer");
} catch (Exception e) {
logger.error("Could not stop the DB2 timer thread", e);
}
}
Note: Since the DB2 driver JAR appears to be obfuscated, the timer storage (com.ibm.db2.jcc.am.iq.a) will probably be different for other driver versions. Also, the constructor of the class you're subclassing might have side effects, in my case there are none.
How I got to this solution
Get the exception
java.lang.NullPointerException
at org.apache.catalina.loader.WebappClassLoaderBase.getResource(WebappClassLoaderBase.java:1600)
at com.ibm.db2.jcc.am.wd.run(wd.java:49)
at java.security.AccessController.doPrivileged(Native Method)
at com.ibm.db2.jcc.am.GlobalProperties.a(GlobalProperties.java:146)
at com.ibm.db2.jcc.am.GlobalProperties.d(GlobalProperties.java:100)
at com.ibm.db2.jcc.am.dr.run(dr.java:124) <------- point of interest <----------
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
The main class for the timer is com.ibm.db2.jcc.am.dr.
Using IntelliJ, I set a breakpoint in its constructor. Wait for the breakpoint to hit:
Go to where it's instantiated, in my case in GlobalProperties. Look on what timer it is scheduled.
Find a way to access iq.a: Since this is a static protected field, we can inherit from iq and from inside that class, access the static field of the parent class to call cancel() on a.
This is a confirmed bug in the IBM JDBC driver version 4.19 (timer task that cannot be disabled). The workaround is to downgrade to version 4.18.
Fix for version 4.19.66:
public void contextDestroyed(ServletContextEvent servletContextEvent) {
// This fixes the JDBC driver not unloading corectly on a context reload for DB2 JDBC 4.19.66
try {
System.out.println("Trying to stop the DB2 timer thread");
new com.ibm.db2.jcc.am.tp() {
{
if (a != null) {
a.cancel();
} else {
System.out.println("Timer is null, skipped");
}
}
};
System.out.println("Stopped the timer");
} catch (Exception e) {
System.out.println("Could not stop the DB2 timer thread " + e.getMessage());
}
}

Accessing Tomcat Monitors using Java code

I am very new to JMX. I am trying to log the tomcat statistics like threads used, cache, sessions and other standard values. I am trying to achieve this with java code.
I have done the following things as of now. (I am trying to access the values of a local tomcat 6.0 monitor on windows)
1)I have added the following options in the catalina.bat
set CATALINA_OPTS=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9004 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
After that I restarted the tomcat server.
2) Then I wrote the following code.
package com.ss.fg;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
public class SystemConfigManagement
{
static MBeanServer connection = ManagementFactory.getPlatformMBeanServer();
public static void main(String[] args) throws Exception {
getActiveSession();
}
public static void getActiveSession()throws Exception
{
ObjectName name=new ObjectName("Catalina:type=Manager,path=/MMDisplay,host=localhost");
String attrValue = ManagementFactory.getPlatformMBeanServer().getAttribute(name, "activeSessions").toString();
System.out.println(attrValue);
}
}
I even tried context instead of path.
I am getting the following exception
Exception in thread "main" javax.management.InstanceNotFoundException: Catalina:type=Manager,path=/MMDisplay,host=localhost
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getMBean(Unknown Source)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getAttribute(Unknown Source)
at com.sun.jmx.mbeanserver.JmxMBeanServer.getAttribute(Unknown Source)
at com.softsmith.floodgates.SystemConfigManagement.getActiveSession(SystemConfigManagement.java:15)
at com.softsmith.floodgates.SystemConfigManagement.main(SystemConfigManagement.java:10)
How can I resolve this issue?
Should I add Some jar files, or should I do some other settings..
Please help
When using
MBeanServer connection = ManagementFactory.getPlatformMBeanServer();
you are actually connectiong to the MBean-Server of the JVM running your program, not to that of your tomcat-instance, so it doesn't know of the Catalina-MBeans.
To establish a connection to a remote jvm try something like:
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://servername:9999/jmxrmi");
JMXConnector connector = JMXConnectorFactory.connect(url);
connector.connect();
MBeanServerConnection server = connector.getMBeanServerConnection();
//do work here
ObjectName name = new ObjectName("Catalina:type=Manager,path=/manager,host=localhost");
String attrValue = mb.getAttribute(name, "activeSessions").toString();
System.out.println(attrValue);
//..and don't forget to close the connection
connector.close();
If the error is still there make sure you are using the correct object-name.
When i using
MBeanServer connection = ManagementFactory.getPlatformMBeanServer();
i am actually connectiong to the MBean-Server of the JVM running my program, not to that of my tomcat-instance, so it doesn't know of the Catalina-MBeans.
so i try to connected remotly to jmx but have error like this :
java.io.IOException: Failed to retrieve RMIServer stub: javax.naming.CommunicationException [Root exception is java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is....
and now i solve :
for first i added catalina-jmx-remote.jar to TOMCAT_HOME/lib directory of Tomcat and then configure the listener on server.xml i added the following
snippet under the tag :
<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002" useLocalPorts="true" />
and finally i set the following sentence in my catalina.bat :
JAVA_OPTS="$JAVA_OPTS -Djava.rmi.server.hostname=localhost -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"

Connecting to HPQC from 64bit JAVA

While trying to cennect HPQC from a 64bit machine(having 64bit JAVA, and ECLIPSE), I am getting the below mentioned exception:
Exception in thread "main" com4j.ExecutionException: com4j.ComException: 80040154 CoCreateInstance failed : Class not registered : .\com4j.cpp:153
at com4j.ComThread.execute(ComThread.java:203)
at com4j.Task.execute(Task.java:25)
at com4j.COM4J.createInstance(COM4J.java:97)
at com4j.COM4J.createInstance(COM4J.java:72)
at com.qc.ClassFactory.createTDConnection(ClassFactory.java:16)
at com.java.Test.main(Test.java:25)
Caused by: com4j.ComException: 80040154 CoCreateInstance failed : Class not registered : .\com4j.cpp:153
at com4j.Native.createInstance(Native Method)
at com4j.COM4J$CreateInstanceTask.call(COM4J.java:117)
at com4j.COM4J$CreateInstanceTask.call(COM4J.java:104)
at com4j.Task.invoke(Task.java:51)
at com4j.ComThread.run0(ComThread.java:153)
at com4j.ComThread.run(ComThread.java:134)
PFB my code:
public static void main(String[] args) {
// TODO Auto-generated method stub
//QC url
String url = "https://qc_link/qcbin";
//username for login
String username = "username";
//password for login
String password = "password";
//domain
String domain = "domain";
//project
String project = "project";
ITDConnection itdc = ClassFactory.createTDConnection();
System.out.println("Connecting");
itdc.initConnectionEx(url);
itdc.connectProjectEx(domain, project, username, password);
System.out.println("Connected......");
}
}
The above code works fine for 32bit Java and Eclipse.
Any help would be highly appreciated.
Regards,
Parag
The COM API's are 32-bit only and cannot be accessed by a 64-bit process. I have the same problem with .NET applications where I'm stuck in 32-bit until I can move to the REST API (which is bit-less) or host my COM-reliant code in an external process.
This issue can be solved by registering all 3 .dll files in c:\Windows\SysWow64. instead of c:\Windows\System32.
Hope it might be helpful:)

How to initialize JRockit MBean tree

I have the following code that just lists all MBean names found in platform MBean server:
public static void main(final String[] args) throws Exception {
initJMX();
}
#SuppressWarnings("unchecked")
private static void initJMX() throws IOException, MalformedURLException, AttributeNotFoundException,
InstanceNotFoundException, MalformedObjectNameException, MBeanException, ReflectionException,
NullPointerException {
JMXConnector jmxc = null;
final Map<String, String> map = new HashMap<String, String>();
jmxc = JMXConnectorFactory.newJMXConnector(createConnectionURL("localhost", 7788), map);
jmxc.connect();
final MBeanServerConnection connection = jmxc.getMBeanServerConnection();
final String[] domains = connection.getDomains();
for (final String domain : domains) {
final Set<ObjectName> mBeans = connection.queryNames(new ObjectName(domain + ":*"), null);
for (final ObjectName name : mBeans) {
System.out.println(name);
}
}
jmxc.close();
}
When I try to run this code with JRockit 1.5.0_4.0.1 with the following parameters:
-Xmanagement:ssl=false,authenticate=false,autodiscovery=false,port=7788
And it prints the following list:
[INFO ][mgmnt ] Remote JMX connector started at address localhost:7788
[INFO ][mgmnt ] Local JMX connector started
com.oracle.jrockit:type=FlightRecorder
java.util.logging:type=Logging
JMImplementation:type=MBeanServerDelegate
java.lang:type=Compilation
java.lang:type=GarbageCollector,name=Garbage collection optimized for throughput Young Collector
java.lang:type=MemoryManager,name=Class Manager
java.lang:type=MemoryPool,name=ClassBlock Memory
java.lang:type=GarbageCollector,name=Garbage collection optimized for throughput Old Collector
java.lang:type=Runtime
java.lang:type=MemoryPool,name=Nursery
java.lang:type=ClassLoading
java.lang:type=Threading
java.lang:type=MemoryPool,name=Class Memory
java.lang:type=OperatingSystem
java.lang:type=Memory
java.lang:type=MemoryPool,name=Old Space
But if I put a breakpoint before a call to initJMX method and at that point connect to that JVM with JRMC, then JRMC displays much more MBeans and also after I continue program execution it also prints a different list which contains more JRockit related MBeans:
[INFO ][mgmnt ] Remote JMX connector started at address T500W7AAD:7788
[INFO ][mgmnt ] Local JMX connector started
com.oracle.jrockit:type=FlightRecorder
oracle.jrockit.management:type=PerfCounters
oracle.jrockit.management:type=Compilation
oracle.jrockit.management:type=Log
oracle.jrockit.management:type=Profiler
oracle.jrockit.management:type=MemLeak
oracle.jrockit.management:type=JRockitConsole
oracle.jrockit.management:type=GarbageCollector
oracle.jrockit.management:type=Runtime
oracle.jrockit.management:type=Threading
oracle.jrockit.management:type=DiagnosticCommand
oracle.jrockit.management:type=Memory
java.util.logging:type=Logging
JMImplementation:type=MBeanServerDelegate
java.lang:type=Compilation
java.lang:type=GarbageCollector,name=Garbage collection optimized for throughput Young Collector
java.lang:type=MemoryManager,name=Class Manager
java.lang:type=MemoryPool,name=ClassBlock Memory
java.lang:type=GarbageCollector,name=Garbage collection optimized for throughput Old Collector
java.lang:type=Runtime
java.lang:type=MemoryPool,name=Nursery
java.lang:type=ClassLoading
java.lang:type=Threading
java.lang:type=MemoryPool,name=Class Memory
java.lang:type=OperatingSystem
java.lang:type=Memory
java.lang:type=MemoryPool,name=Old Space
Is there a way to say JRockit to initialize those beans automatically on JVM startup without a need of explicit JRMC connection? The problem is that I'm trying to write some code that reuses some of those MBeans, but they are not available until I connect with JRMC.
UPDATE: This seems to be JRockit jdk1.5.0_4.0.1 problem. As same code works as expected on JRockit jdk6.0_4.1.0.
This appears to be a problem with the Windows version of JRockit that I use:
java version "1.5.0_24"
Java(TM) Platform, Standard Edition for Business (build 1.5.0_24-b02)
Oracle JRockit(R) (build R28.0.1-21-133393-1.5.0_24-20100512-2131-windows-x86_64, compiled mode)
Same code works as expected on latest JRockit for JDK 1.6.0 on Windows:
java version "1.6.0_29"
Java(TM) SE Runtime Environment (build 1.6.0_29-b11)
Oracle JRockit(R) (build R28.2.2-7-148152-1.6.0_29-20111221-2104-windows-x86_64, compiled mode)
and on the same JRockit version, but for Linux:
java version "1.5.0_24"
Java(TM) Platform, Standard Edition for Business (build 1.5.0_24-b02)
Oracle JRockit(R) (build R28.1.0-123-138454-1.5.0_24-20101014-1350-linux-x86_64, compiled mode)
try your query with object names of *:*
final Set<ObjectName> mBeans = connection.queryNames(new ObjectName("*:*"),
Maybe there is more than one MBeanServer in the JRockit that the JRMC finds all MBeanServers.

Rmi connection refused with localhost

I have a problem using java rmi:
When I'm trying to run my server, I get a connectException (see below).
Exception happens when executing the rebind method:
Runtime.getRuntime().exec("rmiregistry 2020");
MyServer server = new MyServer();
Naming.rebind("//localhost:2020/RemoteDataPointHandler", server);
when using rmi://localhost:2020/RemoteDataPointHandler instead, it doesn't work either. Also using the default port does not work. I also tried using the 127.0.0.1 ip-address, but with the same effect.
my runtime args:
-Djava.security.policy=java.security.AllPermission
Exception in thread "main" java.rmi.ConnectException: Connection refused to host: localhost; nested exception is:
java.net.ConnectException: Connection refused
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at java.rmi.Naming.rebind(Naming.java:160)
at be.fortega.knx.server.Main.(Main.java:25)
at be.fortega.knx.server.Main.main(Main.java:16)
Caused by: java.net.ConnectException: Connection refused
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:433)
at java.net.Socket.connect(Socket.java:524)
at java.net.Socket.connect(Socket.java:474)
at java.net.Socket.(Socket.java:371)
at java.net.Socket.(Socket.java:184)
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:569)
... 7 more
had a simliar problem with that connection exception. it is thrown either when the registry is not started yet (like in your case) or when the registry is already unexported (like in my case).
but a short comment to the difference between the 2 ways to start the registry:
Runtime.getRuntime().exec("rmiregistry 2020");
runs the rmiregistry.exe in javas bin-directory in a new process and continues parallel with your java code.
LocateRegistry.createRegistry(2020);
the rmi method call starts the registry, returns the reference to that registry remote object and then continues with the next statement.
in your case the registry is not started in time when you try to bind your object
It seems to work when I replace the
Runtime.getRuntime().exec("rmiregistry 2020");
by
LocateRegistry.createRegistry(2020);
anyone an idea why? What's the difference?
You need to have a rmiregistry running before attempting to connect (register) a RMI service with it.
The LocateRegistry.createRegistry(2020) method call creates and exports a registry on the specified port number.
See the documentation for LocateRegistry
One difference we can note in Windows is:
If you use Runtime.getRuntime().exec("rmiregistry 1024");
you can see rmiregistry.exe process will run in your Task Manager
whereas if you use Registry registry = LocateRegistry.createRegistry(1024);
you can not see the process running in Task Manager,
I think Java handles it in a different way.
and this is my server.policy file
Before running the the application, make sure that you killed all your existing
javaw.exe and rmiregistry.exe corresponds to your rmi programs which are
already running.
The following code works for me by using Registry.LocateRegistry() or
Runtime.getRuntime.exec("");
// Standard extensions get all permissions by default
grant {
permission java.security.AllPermission;
};
VM argument
-Djava.rmi.server.codebase=file:\C:\Users\Durai\workspace\RMI2\src\
Code:
package server;
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.Remote;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class HelloServer
{
public static void main (String[] argv)
{
try {
if(System.getSecurityManager()==null){
System.setProperty("java.security.policy","C:\\Users\\Durai\\workspace\\RMI\\src\\server\\server.policy");
System.setSecurityManager(new RMISecurityManager());
}
Runtime.getRuntime().exec("rmiregistry 1024");
// Registry registry = LocateRegistry.createRegistry(1024);
// registry.rebind ("Hello", new Hello ("Hello,From Roseindia.net pvt ltd!"));
//Process process = Runtime.getRuntime().exec("C:\\Users\\Durai\\workspace\\RMI\\src\\server\\rmi_registry_start.bat");
Naming.rebind ("//localhost:1024/Hello",new Hello ("Hello,From Roseindia.net pvt ltd!"));
System.out.println ("Server is connected and ready for operation.");
}
catch (Exception e) {
System.out.println ("Server not connected: " + e);
e.printStackTrace();
}
}
}
it seems that you should set your command as an String[],for example:
String[] command = new String[]{"rmiregistry","2020"};
Runtime.getRuntime().exec(command);
it just like the style of main(String[] args).

Categories