Java Remote method invocation - java

If i call this server method with the client from different location iam getting following error.If i run the client from same location where the server is there I am getting output.
Please give some soltuions to call my rmi server with rmi client from different location.
Error
Exception in thread "main" java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.lang.ClassNotFoundException: com.transform.xsl.XslFoTransformer_Stub (no security manager: RMI class loader disabled)
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at java.rmi.Naming.lookup(Naming.java:101)
at com.transform.xsl.RmiClient.main(RmiClient.java:15)
Caused by: java.lang.ClassNotFoundException: com.transform.xsl.XslFoTransformer_Stub (no security manager: RMI class loader disabled)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:394)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:184)
at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:637)
at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:264)
at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:222)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1610)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1515)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1769)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
... 3 more
Code ======
import java.io.File;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface XslFoTransformerInterface extends Remote {
public byte[] doTransform(File stylesheet, File datafile) throws Throwable,RemoteException;
}
public class XslFoTransformer extends UnicastRemoteObject implements XslFoTransformerInterface {
protected XslFoTransformer() throws RemoteException {
super();
}
public byte[] doTransform(File stylesheet, File datafile) throws Exception {
String fileName = datafile.getName();
int pos = fileName.lastIndexOf(".");
if (pos > 0) {
fileName = fileName.substring(0, pos);
}
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
File file = new File(fileName + ".xsl-fo");
try {
// File stylesheet = new
// File("C:\\Users\\Q811213\\Documents\\XSLT\\files\\ECGSearchResultsPDF_changed1.xsl");
// File datafile = new
// File("C:\\Users\\Q811213\\Documents\\XSLT\\files\\NEWDATA.xml");
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(datafile);
TransformerFactory tFactory = TransformerFactory.newInstance();
StreamSource stylesource = new StreamSource(stylesheet);
Transformer transformer = tFactory.newTransformer(stylesource);
DOMSource source = new DOMSource(document);
ByteArrayOutputStream bos=new ByteArrayOutputStream();
StreamResult result=new StreamResult(bos);
transformer.transform(source, result);
byte [] array=bos.toByteArray();
return array;
} catch (Exception e) {
throw e;
}}}
--Rmi server class
public class RmiServer {
public static void main(String args[]) throws Exception{
try{
XslFoTransformerInterface stub=new XslFoTransformer();
Naming.rebind("rmi://localhost:1099/Xsl-Fo_Transform",stub);
}catch(Exception e){
throw e;
}
}
}
--Rmi client created in different location
public class RmiClient {
public static void main(String args[]) throws Throwable {
try {
XslFoTransformerInterface stub = (XslFoTransformerInterface) Naming
.lookup("rmi://localhost:1099/Xsl-Fo_Transform");
System.out.println("stub is ready" + stub);
File f1 = new File(
"C:\\Users\\s811213\\osbwstest\\XSL-FO_Transformer\\files\\ECGSearchResultsPDF_changed1.xsl");
File f2 = new File(`enter code here`
"C:\\Users\\s811213\\osbwstest\\XSL-FO_Transformer\\files\\NEWDATA.xml");
try {
byte[] f = stub.doTransform(f1, f2);
}cartch(){}
}}
If i call this server method with the client from different location iam getting following error.If i run the client from same location where the server is there i am getting output.
Please give some soltuions to call my rmi server with rmi client from different location.

You need to deploy the stub class named in the exception to the client.

In RMI client
XslFoTransformerInterface stub = (XslFoTransformerInterface) Naming
.lookup("rmi://localhost:1099/Xsl-Fo_Transform");
you need to change localhost to server ip

I'm not sure if you running your program in different locations (no the server machine) with the updated version of your code for ip which you hard coded for localhost.
If this is not the problem, you must be sure that you placed the XslFoTransformerInterface class in your client codes in the same package as it is in server codes.
Also in the future if you have some Serializable POJO classes as the arguments or the return types of you remote methods, same rule is applied for them. Always put them in the same package as they reside is the server codes.
Good Luck.

Related

InDesign Server IdsException Java Corba

We are facing an error while running the sample program given below using java API CORBA on InDesign server. we have enabled CORBA on the server. Exception occurred during document create method, also upon calling other app methods like getChildDocuments() or getName(), etc. you help will be appreciated.
Program giving exception(IDL:com/adobe/ids/IdsException) at this line:
Document myDoc = myApp.addDocument(OptArg.noDocumentPreset());
ORBD service running with port 1050.
Exception details:
"C:\Program Files\Java\jdk1.8.0_301\bin\java.exe"
Exception #30465:
com.adobe.ids.IdsException: IDL:com/adobe/ids/IdsException:1.0
at com.adobe.ids.IdsExceptionHelper.read(Unknown Source)
at com.adobe.ids.basics._ApplicationStub.getFullName(Unknown Source)
at com.adobe.ids.sdk.ImprovedHelloWorld.main(ImprovedHelloWorld.java:40)
Exception in thread "main" com.adobe.ids.IdsException: IDL:com/adobe/ids/IdsException:1.0
at com.adobe.ids.IdsExceptionHelper.read(Unknown Source)
at com.adobe.ids.basics._ApplicationStub.consoleout(Unknown Source)
at com.adobe.ids.sdk.ImprovedHelloWorld.main(ImprovedHelloWorld.java:85)
Program sample:
public static void main(String[] args) throws Exception
{
String iorFile = "d:\\ior.txt";
Properties props = new Properties();
props.put("port", "1050");
props.put("org.omg.CORBA.ORBInitialHost", "localhost");
BufferedReader iorIn = new BufferedReader(new FileReader(iorFile));
String application_IOR = iorIn.readLine();
ORB orb = ORB.init(new String [] {iorFile}, props);
Object object = orb.string_to_object(application_IOR);
Application myApp = ApplicationHelper.narrow(object);
Document arr[] = myApp.getAllChildDocuments();
Document myDoc = myApp.addDocument(OptArg.noDocumentPreset());
orb.shutdown(true); // true to wait for completion
orb.destroy();
}

RMI dynamic class loading in java, how to separate and launch code on localhost?

I have a bit confusion about how dynamic class loading mechanism works. I implemented below classes and when they are all in the same src directory and i launch them from my ide, server and client works. But when i separate them i can't make it work. There are many guides that explaining how RMI works etc but they don't explain how should i separate files and launch them one everything is ok.
So what i have done:
Compiled all classes and obtained corrisponding .class files. Then i created a folder and subfolders to separate client, server and common classes:
home/
|-myuser/
|--rmitest/
|--server/
| Server.class
|-- client/
| Client.class, client.policy
|-- common/
NotifyEventImpl.class, NotifyEventInterface.class, ServerImpl.class, ServerInterface.class
This is a homework question server and client will both work on localhost. Anyway, then whe i launch server with
$ java -Djava.rmi.server.codebase=/home/myuser/rmitest/common/ Server .
it can't find classes
Exception in thread "main" java.lang.NoClassDefFoundError: ServerImpl
at Server.main(Server.java:15)
Caused by: java.lang.ClassNotFoundException: ServerImpl
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)
... 1 more
So how should i do it to get it work? My seperation of classes is correct? How should i launch server and client? Thanks.
Below you find my classes:
public interface ServerInterface extends Remote{
void registerForCallback(NotifyEventInterface clientInterface)
throws RemoteException;
}
public class ServerImpl extends UnicastRemoteObject implements ServerInterface {
private List<NotifyEventInterface> clients;
public ServerImpl() throws RemoteException{
super();
clients = new ArrayList<NotifyEventInterface>();
}
public synchronized void registerForCallback(NotifyEventInterface ClientInterface) throws RemoteException{
if(!clients.contains(ClientInterface)){
clients.add(ClientInterface);
System.out.println("New client registered");
}
}
public void update(int value) throws RemoteException {
doCallbacks(value);
}
private synchronized void doCallbacks(int value) throws RemoteException {
System.out.println("Starting callbacks");
Iterator i = clients.iterator();
while(i.hasNext()){
NotifyEventInterface client = (NotifyEventInterface) i.next();
client.notifyEvent(value);
}
System.out.println("Callbacks complete");
}
}
public class Server {
public static void main(String[] args) {
ServerImpl serverObj = new ServerImpl();
int portNum = 39000;
startRegistry(portNum);
String registryUrl = "//:" + portNum + "/common";
Naming.rebind(registryUrl, serverObj);
System.out.println("Server is ready");
while(true){
int val = (int) (Math.random() * 1000);
System.out.println("New update " + val);
serverObj.update(val);
Thread.sleep(1500);
}
}
private static void startRegistry(int rmiPortNum) throws RemoteException{
try {
Registry registry = LocateRegistry.getRegistry(rmiPortNum);
registry.list( );
} catch (RemoteException ex) {
System.out.println("RMI registry is not located at port " + rmiPortNum);
Registry registry = LocateRegistry.createRegistry(rmiPortNum);
System.out.println("RMI registry created at port " + rmiPortNum);
}
}
}
public interface NotifyEventInterface extends Remote {
void notifyEvent(int value) throws RemoteException;
}
public class NotifyEventImpl implements NotifyEventInterface{
public NotifyEventImpl() throws RemoteException{
super();
}
#Override
public void notifyEvent(int value) throws RemoteException {
String returnMessage = "Update event received " + value;
System.out.println(returnMessage);
}
}
Compiled all classes and obtained corrisponding .class files. Then i created a folder and subfolders to separate client, server and common classes
Wrong. You should separate them first, at source code level, with corresponding package statements in the source code. Then compile. The compiler will then put the .class files into a directory structure corresponding to the package hierarchy.
NB ServerImpl is not a common class. It is only used by the server.

Calling Matlab by JADE agent as multi-threading for multiple connections

I am working on JADE (Java) project that connects Matlab by a TCP connection with client-server sockets. Here, JADE creates a server socket and Matlab creates a client socket. I am retrieving some data from Matlab to Java (JADE). The following is my code where I am calling Matlab by JADE through Agent. (1) The issue is I cannot re-run it without re-starting the program again. I believe that I require a multithread java instance with multithread Matlab instance that could connect and synchronize each other. However, I found that Matlab is a single thread. The program throws binding error.
WARNING: Error adding ICP jade.imtp.leap.JICP.JICPPeer#1dbb27d[Cannot bind server socket to localhost port 1099].
jade.core.AgentContainerImpl joinPlatform
SEVERE: Communication failure while joining agent platform: No ICP active
jade.core.IMTPException: No ICP active
I want to run it multiple times without manually re-starting. Here is my JADE code (took help from https://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html):
public class MatlabComAgent extends Agent
{
ServerSocket srvr = null;
Socket skt = null;
BufferedReader in;
PrintWriter out;
String ip = "localhost";
String filePath;
int port = 1234;
protected void setup()
{
// Get arguments
Object[] args = getArguments();
filePath = (String) args[0];
// Create the TCP connection
try
{
// Create server and socket
srvr = new ServerSocket(port);
skt = srvr.accept();
// Create writer and reader to send and receive data
out = new PrintWriter(skt.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(skt.getInputStream()));
}
catch (IOException e)
{
e.printStackTrace();
}
// Send a message to the tester to say its can start sending requests
sendMessage("Tester","","start-now",ACLMessage.INFORM);
// Run behavior
CommWithMatlab commWithMatlab = new CommWithMatlab();
addBehaviour(commWithMatlab);
} // End setup
Code for Matlab connection:
% Create TCP/IP object 't'. Specify server machine and port number.
% Open the connection with the server
t = tcpip('localhost', 1234);
set(t, 'InputBufferSize', 30000);
set(t, 'OutputBufferSize', 30000);
pause(0.1)
fopen(t);
disp('Connection with JADE established')
I found interesting notes on "socket server which allows multiple connections via threads and Java" Creating a socket server which allows multiple connections via threads and Java page, however, I am not able to do it completely what is said here. May be I am missing something here. (2) I am confused should I edit my Matlab code and/or JADE code for multi-threading.
Here is my code that I tried:
protected void setup()
{
// Get arguments
Object[] args = getArguments();
filePath = (String) args[0];
// Create the TCP connection
try
{
srvr = new ServerSocket(port);
Runnable connectionHandler = new ConnectionHandler(skt);
new Thread(connectionHandler).start();
}
catch (IOException e)
{
e.printStackTrace();
}
Here is new ConnectionHandler class:
public class ConnectionHandler implements Runnable {
private Socket sk=null; //initialize in const'r
BufferedReader in;
PrintWriter out;
public ConnectionHandler(ServerSocket skt) throws IOException
{
sk = skt.accept();
out = new PrintWriter(sk.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(sk.getInputStream()));
}
public void run() {
try
{
// Create writer and reader to send and receive data
out = new PrintWriter(sk.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(sk.getInputStream()));
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
But I got some erorr "java.lang.NullPointerException". Can someone help me to properly code it, what I am missing. Also, (3) this run() in ConnectionHandler class will be invoked automatically? I was confused so I create writer and reader inside Connectionhandler class and its run(). Can I simply make my MatlabComAgent class as multithread without adding any new class. I can make my class as
public class MatlabComAgent extends Agent implements Runnable
{....
....
}
Should I also put the following inside ConnectionHandler class?
// Send a message to the tester to say its can start sending requests
sendMessage("Tester","","start-now",ACLMessage.INFORM);
// Run behavior
CommWithMatlab commWithMatlab = new CommWithMatlab();
addBehaviour(commWithMatlab);
Here, CommWithMatlab class extends SimpleBehavior containg required actions that further passes commands from Matlab to PowerWorld (using another connection). One example is like:
class CommWithMatlab extends SimpleBehaviour
{
private static final long serialVersionUID = 8966535884137111965L;
#Override
public void action()
{
// Wait for a message from another agent requesting something
ACLMessage msg = blockingReceive();
// If this is to open a case
if(msg.getConversationId().equals(OPEN_CASE))
{
openCase(msg.getContent());
}
}
I can simple pass arguments to addagent() and can call runJade(). The following are my JADE run functions using agents:
//Runs JADE and starts the initial agents
public static void runJade() throws ControllerException
{
// Launch JADE platform
Runtime rt = Runtime.instance();
Profile p;
p = new ProfileImpl();
cController = rt.createMainContainer(p);
rt.setCloseVM(true);
// Launch Powerworld interface agent
addAgent(PWRWORLD_NAME, PWRWORLD_CLASS, null);
addAgent(PWRWORLD_TESTER_NAME, PWRWORLD_TESTER_CLASS, null);
//addAgent(PWRWORLD_TESTER_NAME2, PWRWORLD_TESTER_CLASS2, null);
}
private static void addAgent(String name, String type, String arg) throws ControllerException
{
Object[] argsObj = {arg};
AgentController ac = cController.createNewAgent(name, type, argsObj);
ac.start();
}
(4) I have a different program that also creates the same connection. When I try to run one program when other is running, it again throws binding error. However, these programs are completely separate. One program uses port 1234 and other 1239. However, system always assign local port to 1099 to both programs, hence throw binding error in this case.
Any help is appreciable!
Unfortunately, it is not possible to use matlabcontrol over a distributed network. I checked.

connecting to magento api using soap java

magento api using soap doesn't work due to missing magento-api.properties files, can someone help?
public class testConnection {
public static void main(String[] args) throws AxisFault {
String user = "rajeshvishnani";
String pass = "123456";
String host = "http://cypherincorporated.co.in/magento/index.php/api/soap?wsdl";
SoapConfig soapConfig = new SoapConfig(user, pass, host);
MagentoSoapClient magentoSoapClient = MagentoSoapClient.getInstance(soapConfig);
magentoSoapClient.setConfig(soapConfig);
}
}
Exception in thread "main" java.lang.IllegalArgumentException: could not load [magento-api.properties] as a classloader resource
at com.google.code.magja.utils.PropertyLoader.loadProperties(PropertyLoader.java:106)
at com.google.code.magja.utils.PropertyLoader.loadProperties(PropertyLoader.java:123)
at com.google.code.magja.soap.MagentoSoapClient.getInstance(MagentoSoapClient.java:69)
at magentomanager.testConnection.main(testConnection.java:15)
Try changing the url to 'http://yoursite.com/api/v2_soap/index?wsdl=1'.
Please provide more details.
Not sure about java exception but you can try following link.
Link

How does one configure CXF generated client for preemptive HTTP auth?

I have a client that was generated by CXF using a local wsdl file. The client connects OK, and I get an expected 401 error from the web server.
The problem I've run into is not being able to properly configure preemptive auth in the client.
I've tried a number of things to no avail. The majority of examples on the web seem to focus on Spring, rather a plain old Java approach.
I'm including the main portion of the client. If anyone can give me an example of how this should be configured, I'd appreciate it. Note that I'm not looking for anything fancy. I just need to be able to authenticate and call the services.
public final class ServiceNowSoap_ServiceNowSoap_Client {
private static final QName SERVICE_NAME = new QName(
"http://www.service-now.com/foo",
"ServiceNow_foo");
private ServiceNowSoap_ServiceNowSoap_Client() {
}
public static void main(String args[]) throws java.lang.Exception {
URL wsdlURL = ServiceNowCmdbCiComm.WSDL_LOCATION;
if (args.length > 0 && args[0] != null && !"".equals(args[0])) {
File wsdlFile = new File(args[0]);
try {
if (wsdlFile.exists()) {
wsdlURL = wsdlFile.toURI().toURL();
} else {
wsdlURL = new URL(args[0]);
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
ServiceNowFoo ss = new ServiceNowFoo(wsdlURL,
SERVICE_NAME);
ServiceNowSoap port = ss.getServiceNowSoap();
{
System.out.println("Invoking deleteRecord...");
java.lang.String _deleteRecord_sysId = "";
java.lang.String _deleteRecord__return = port
.deleteRecord(_deleteRecord_sysId);
System.out.println("deleteRecord.result=" + _deleteRecord__return);
}
System.exit(0);
}
}
Another aproach would be:
import javax.xml.ws.BindingProvider;
public class CxfClientExample {
public static void main(String[] args) throws Exception {
String endPointAddress = "http://www.service-now.com/foo";
ServiceNowFoo service = new ServiceNowFoo();
ServiceNowFooPortType port = service.getServiceNowFoo();
BindingProvider bindingProvider = (BindingProvider) port;
bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endPointAddress);
bindingProvider.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "theusername");
bindingProvider.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "thepassword");
String deleteRecord_return = port.deleteRecord("");
System.out.println("deleteRecord.result=" + deleteRecord_return);
}
}
OK, I figured this out. Pretty straightforward when it comes down to it. Hope this saves somebody a couple of minutes...
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
private static final QName SERVICE_NAME = new QName(
"http://www.service-now.com/foo",
"ServiceNow_foo");
private ServiceNowSoap_ServiceNowSoap_Client() {
}
public static void main(String args[]) throws java.lang.Exception {
URL wsdlURL = ServiceNowFoo.WSDL_LOCATION;
if (args.length > 0 && args[0] != null && !"".equals(args[0])) {
File wsdlFile = new File(args[0]);
try {
if (wsdlFile.exists()) {
wsdlURL = wsdlFile.toURI().toURL();
} else {
wsdlURL = new URL(args[0]);
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
ServiceNowFoo ss = new ServiceNowFoo(wsdlURL,
SERVICE_NAME);
ServiceNowSoap port = ss.getServiceNowSoap();
Client client = ClientProxy.getClient(port);
HTTPConduit http = (HTTPConduit) client.getConduit();
http.getAuthorization().setUserName("theusername");
http.getAuthorization().setPassword("thepassword");
// Do your work here.
}
You can also use interceptors. One benefit of using interceptor is that you can attach it to all your clients , streamlining your pre-emptive authentication approach.
Take a look at :
How do i modify HTTP headers for a JAX-WS response in CXF?
Hi Friend you have configured the authentication part after invoking the webservice, how does this works ?
Client client = ClientProxy.getClient(port);
HTTPConduit http = (HTTPConduit) client.getConduit();
http.getAuthorization().setUserName("theusername");
http.getAuthorization().setPassword("thepassword");

Categories