RMI IIOP client object as callback - java

I'm trying to build rmi-iiop application (very simple chat).
I need server to be able to communicate with client so my thinking was to create interface of connected user:
public interface UserInterface extends Remote {
public void receiveMessage(String message) throws RemoteException;
}
Then on client side create User class with methods server can execute('receiveMessage'):
public class User extends PortableRemoteObject implements UserInterface {
protected User() throws RemoteException {
super();
}
#Override
public void receiveMessage(String message) throws RemoteException {
client.addMessageToGUI();
}
}
I use rmic -iiop Chat User which generates _Chat_Tie.class _ChatInterface_Stub.class _User_Tie.class _UserInterface_Stub.class
After placing all files on server side and client side and running the application I get following error:
java.rmi.StubNotFoundException: Stub class not found: User_Stub; nested exception is:
I guess the difference here is that Chat class is created on server and then client uses it using interface (which works fine), but user class has to be created on client side, so client works partly as a server.
My question is similar to Java RMI - Making the client a server
but for rmi-ioop implementation.
So in to words - how can I send local object reference to server so it could perform operations on it?
Thanks!
Leonty

you create a server interface like:
public interface ChatServer extends Remote {
public void registerUser(UserInterface user) throws RemoteException;
}

What I was missing is "Tie" class on client side (_User_Tie.class). Usually it's not needed but in case when object is created on client side - I needed to supply it also.
Hope it saves some time for someone else in a future :)

Related

Best practice when using rest clients in a servlet container

I am working on a project where we have a big portal running in a tomcat container. Every time the user logs into the portal, some information is retrieved by invoking a rest client. The code looks something like this:
public class RestClient {
private static final String REST_URI = "http://url.tld/to/login/api";
private Client client;
public Client getClient() {
if (client == null) {
client = ClientBuilder.newClient();
}
return client;
}
public LoginData getLoginData(int userId) {
return client
.target(REST_URI)
.path(String.valueOf(userId))
.request(MediaType.APPLICATION_JSON)
.get(LoginData.class);
}
}
I am using Apache CXF as my jax-rs client implementation. As far as I know the client object should be thread safe, so that shouldn't be a problem. But imagine 10000 users are opening the website simultaneously and for each request the above code is executed. Do I get a performance problem? Do I need more than just one client object, maybe a client pool?

Basic websocket with Spring without STOMP and SockJS

I have implemented the following websocket endpoint
#MessageMapping("/socket/{myId}/")
#SendTo("/queue/myqueue")
public MyObject getObject(#DestinationVariable String myId) throws Exception {
return new MyObject("MyId:" + myId);
}
Now how can I send message to that endpoint from one of my service.java class?
There will be front-end client as well, which will read the message from websocket once the service.java class's method send some message to websocket endpoint. I am a little confused that how can I do that?
Any help would be appreciated
When using a raw websocket(without STOMP), the message sent lacks of information to make Spring route it to a specific message handler method (we don't have any messaging protocol), so instead of annotating your controller, you'll have to implement a WebSocketHandler by extending TextWebSocketHandler
public void handleTextMessage(WebSocketSession session, TextMessage message){
}
Checkout an example here spring boot websocket without STOMP and SockJs
You should take a look at SimpMessagingTemplate.
For example, if you want to send a message for a specific user from your service class:
#Autowired
private SimpMessagingTemplate messagingTemplate;
public void sendMessage(User user, String message) {
Objects.requireNonNull(user);
Objects.requireNonNull(message);
messagingTemplate.convertAndSendToUser(user.getUsername(), "/queue/myqueue", message);
}

Spring server send realtime Objects to client

I have a question.
I got a Spring server and a Client (Angularjs).
In my client i got a Rickshaw realtime chart.
When my server get some objects from a 3rd party software, i need it to send it to the client. This happens each 28th seconds.
I tried with websocket, and with SSE and i cannot get it to work.
I need someone to point me at a direction, since im lost atm.
Example.
Our server got a class called Animal.
Then a 3rd party software is sending a new object of Animal (E.g dog-cat) each 28th second.
When the server retrieves this object it, insert it in the DB and send it to the client.
The last part is what i can't make work.
Websocket tryout:
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
#Override
public void configureMessageBroker(MessageBrokerRegistry config){
config.enableSimpleBroker("/MashData/data");
config.setApplicationDestinationPrefixes("/app");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry){
registry.addEndpoint("/mashData").setAllowedOrigins("*").withSockJS();
}
}
And in my controller
#MessageMapping("/mashData")
#SendTo("/MashData/data")
#Async
public MashData insertData(#PathVariable Long id, #RequestBody MashData INCmashData){
*Data created here*
return insertData
}

Different web service object after each call

I am new with Java EE and SOAP. I have tried to create a simple web service application and its client (environment: NetBeans 7.2.1 IDE, GlassFish Server 3.1, Java 1.6).
Web service code:
package simplews;
import javax.jws.*;
#WebService(serviceName = "SimpleWebService")
public class SimpleWebService {
String something = null;
#WebMethod(operationName = "setSomething")
#Oneway
public void setSomething(#WebParam(name = "smth") String smth) {
something = smth;
}
#WebMethod(operationName = "getSomething")
public String getSomething() {
return something;
}
}
Client application code:
package simpleclientapp;
import simplews.*;
public class SimpleClientApp {
public static void main(String[] args) {
SimpleWebService_Service service = new SimpleWebService_Service();
SimpleWebService port = service.getSimpleWebServicePort();
port.setSomething("trololo");
String smth = port.getSomething();
System.out.println(smth);
}
}
Unfortunately, the client application printed out null. After short investigation I have realised, that on the server side a new SimpleWebService object is created for each client call (sounds like stateless approach).
What is wrong here? Why the client port does not refer to the same WS object for each call?
Web services are stateless by nature. In order to keep state between requests, you have to persist the data (in a file,database etc.).
You're right, JAX-WS web services are stateless by default and you can't rely on something thatviolates this premise. Follow a different approach in storing such values. You can read this doc Java TM API for XML Web Services (JAX-WS) Stateful Web Service with JAX-WS RI, if you really want to follow the direction in your post.

Integrate Jersey with RMI

I have a Java Jersey project, where I am running an application. On the other hand I have a project were there is a RMI application how can I put this two to work together. In other words how can I intergrate RMI/IIOP into a Jersey application.
I was thinking of something like this:
#Path("/items")
public class ItemsResource {
#Context
UriInfo uriInfo;
#Context
Request request;
Stuber s = new Stuber();
#GET
public Response get() throws RemoteException {
}
Were I have an external class in the Jersey Project that will work as a client to connect with the RMI/IIOP
public class Stuber {
Context ic;
iRemoteLogic logic;
public Stuber() {
super();
Object objref;
try {
ic = new InitialContext();
objref = ic.lookup("LogicService");
System.out.println("Client: Obtained a ref. to Hello server.");
logic = (iRemoteLogic) PortableRemoteObject.narrow(
objref, iRemoteLogic.class);
What should I add to the Stuber class to be able to work as an RMI/IIOP client?
Thanks :)
NOTE: I followed this tutorial for the RMI/IIOP
You would need to provide somewhere an implementation of iRemoteService that is exported via RMI/IIOP (i.e. PortableRemoteObject), and register it via JNDI as LogicService. I doubt the latter is going to work: surely you will need to provide a protocol and host to JNDI.

Categories

Resources