I don't know very well how to create a proxy in java rmi. My client A invokes the server B (unicast) successfully. Now i want that the client A invokes a proxy server C wich invokes the server B. How i can create the proxy? I need a code example to adapt at my situation.
If you want to proxy just one remote interface, it's easy: just write another implementation of it that looks up and calls the real implementation via RMI, and binds itself to a Registry that the client can lookup.
If you want to do it for arbitrary remote interfaces, it's highly non-trivial, trust me, if you are going to get the proxy to do anything useful, such as access control, SSL, etc. There are commercial products that do this, and I vend one of them.
Related
I'm new in Jini technology. I understand it is used for distributed computing or "network plug and play".
But I don't understand the difference between pure RMI and Jini.
Also, I want to understand when Jini is used.
As indicated in the Wikipedia article (http://en.wikipedia.org/wiki/Jini):
Clients can use the lookup service to retrieve a proxy object to the
service; calls to the proxy translate the call to a service request,
performs this request on the service, and returns the result to the
client. This strategy is more convenient than Java remote method
invocation, which requires the client to know the location of the
remote service in advance.
So basically RMI is a mechanism to perform Java calls between a client and a server that know each other. Jini adds services to lookup services from the clients, so the clients do not need to know where the servers are located beforehand.
Any one dealing with the RMI would certainly have come across this dilemma of how to easily maintain the interfaces to objects providing remote method invocation service to other client applications. Whenever we decide to have a minor change in the method declaration or adding/deleting methods declared in the interface, we have to manually replicate the change in all the clients that would be using that interface for accessing RMI service from a remote server.
Think about having a downloadable (Serializable) agent that has a more stable interface used by the client, and that uses the remote interface to do its job. You can use the codebase feature to ensure its availability to all clients. The agent needs to contain the stub. You can bind the agent to the Registry, or return it from some other remote method.
Or, use JWS to distribute new versions of the clients.
Or, design your remote interfaces more stably so they don't have to change -:)
One of the good workaround I came up with is to
put all the interfaces provided by the RMI server in a separate
project which will pack itself into a jar file when built.
Then just add that jar file as dependency or in the
classpath of the server application which is meant to provide the
RMI service as well as to any of the client applications that
want to use those interfaces for invoking remote methods.
This will ease the task of maintaining RMI interfaces by updating them at just one place. Extra effort of changing method signature in some interface will be limited to changing the application code which calls that method.
Im trying to implement an Observer/Observable pattern on an EC2 instance. I have been able to create the application using RMI relatively simply. However trying to get RMI and the Amazon cloud to work has been neer impossible for client callbacks.
RMI also limits the client applications to being Java based. Hence i've been messing around with JAX-WS in order to use SOAP messages. However i havent been able to come up with a solid way to make callbacks on the client with it.
Does anyone know of a way that i would be able to program in a similar way that RMI works with client callback methods to update Observers when something on my server has been changed, using hopefully a language independent distributed method?
I would be willing to make it so that all my clients must be written in java, but i need to be able to get it working on the EC2 instance which RMI seems incapable of doing callbacks even if i open all TCP ports and use a security manager.
Thanks,
Ben
You could try a messaging solution, something like RabbitMQ.
In this way Observable pushes a message to subscribers (Observers). Completely decoupling your clients from the implementation language/specifics of the EC2 instance.
I have a problem with web services. They are programed in Java and are running on a WASCE server ( both are on the same server).
My problem that i want to solve:
We have two Web services: App1 and App2
In App1 i want to call a function that is in App2. How can i do this? Is this even possible?
I tried creating a soapClient inside the App1 so i can connect to the App2 but that doesn't work.
exp:
I have a client that calls app1 gets data from app1 and send it to app2 then get back the response data from app2 and send it to an other function into the app1.
What i want to do is to skip the client part and do it directly so that app1 can send directly the data to the app2 and then receive an answer do whatever it needs to do.
For the note: Both of the web services use the connection to the database.
Thank you in advance.
(it has been edited with additional data)
What does "doesn't work" mean? Exactly what happens?
Start by generating some client code for App2. Can you use that from some simple Java environment, or say a Servlet. If that works, what happens when you try to call it from inside your App 1 Service implementation code?
However: if these are related services running in the same JVM can you not set up some simpler relationship using java libraries. My preferred way of developing a service is first to develop some useful Java code, and make sure that works, then "wrap" it as a Web Service. In which case I have a callable routine that can just be invoked as Java.
It's definitely possible, with differing levels of complexity and feasibility depending on exactly what it is you want, and the restrictions you place on it.
Probably one of the simplest ways to go about this, if you don't have a problem with the method in App2 being public, is to simply create a web service exposing that method and call if from App1.
If you want App2's method to be essentially "protected", so that it can be called by App1 but not by public clients, then there are several alternative options. Firstly, you could use firewalls or equivalent to prevent external requests to the service URL. Alternatively, you could expose the method through some form of interprocess communication; RMI would be the obvious native one for Java (set up an RMI method in App2 and export this through a manager, then obtain the reference in App1 and invoke the method remotely). Depending on exactly what it is you want to do, you may be better off with a framework that does all this under the covers; e.g. distributed objects through something like Terracotta.
You should give more detail in your question, though - currently the only thing you've really specified is that you want to call "a function" in App2 from App1. There are dozens (if not hundreds) of ways to go about this and the best one(s) will depend on the details of what you're trying to do.
EDIT (in light of comments): It's not the details of what you want to do that are lacking - I understand fine that you want to call some method in App2 from within App1. It's more the architectural details - what languages are both clients coded in, what libraries are you using to do the web services, are both clients on the same machine or separate ones (and if same machine, same JVM or not), are there any firewall issues that could inhibit certain kinds of connectivity, are there any office-political restrictions that could inhibit your options, are there any security restrictions that could do the same (such as whether you can expose the functionality of App2's method publically or not). All of these will shape what is possible and what is optimal - because at the end of the day, all networking is basically I want to use resources on that remote computer from here. Without more architectural specifics, there are literally dozens of ways that you could achieve this.
Regarding exposition: You would create a web service to expose App2's function in the same way you would create any other web service (with the details being dependent on the tool/framework you're using). As an example if you're using a tool that supports the JSR-181 annotations, you'd write a method in App2 that performs this function, and annotate it with #WebMethod. Then you'd ensure that if this method is not part of an existing webservice class you'd annotate its class with #WebService. I was presuming that since you already have a couple of web services, you'd know how to write/define them.
As for accessing the web service from App1, this can be done quite simply by a Java SOAP client. A tool such as WSDL2Java can create a stub class modelling the remote service that you can call; alternatively you can get a richer interface with something like CXF.
What WS library are you using currently, and what errors have you encountered when trying to use it to perform this interaction?
I want to understand how the dynamic proxy stub implementation is actually done behind the scene. According to what I read, by the time a remote object is exported if no pre-generated stub class is found, the RMI runtime would generate a dynamic proxy to act as the stub. That stub is then bound to the RMI Registry and later accessible by some RMI client.
The question is: since the stub is actually a dynamically generated proxy, its class definition would not be available on the client side, then how come the client is still able to retrieve the stub from the RMI Registry? Is there some kind of dynamic class-loading happening behind the scene or does RMI use another technique to work-around this?
Java.lang.reflect.Proxy is serializable and it has special support in ObjectOutputStream and ObjectInputStream. Basically just the interfaces implemented and the invocation handler are serialized, and a new dynamic proxy is constructed from that during deserialization.
RMI does use dynamic classloading - the classpath is sent alongwith the call as a 'classpath annotation' from which the client loads the class. You can look at the RMI implementation for more info - it's available as part of the JDK source. Specifically, the classes ObjectOutputStream and RMIClassloader.
Update: RMI does not start an HTTP server - in fact, you would need your custom solution for this. One of them as you mention can be an HTTP server that you run, make the classes available through the server, and pass the codebase with the HTTP server's address/port in your stubs, so that your clients can download them.