I have a small Java SE application, it´s practically a fat client sitting on top of a database. To further my Java skills, I decided to make a client-server application out of it. The server application communicates with the database and handles all kinds of lengthy operations, while the client application only receives the results, mostly ArrayLists of moderate length and primitives.
To this end, I started reading on RMI and did the Oracle tutorial, which I found surprisingly difficult to understand and even get to work.
Is there anything else I can use instead of RMI, without having to dive into JavaEE?
One way I would suggest would be to use JSON as the format for data exchange. You can use GSON to convert the data from Java objects to JSON and back. The transport could be done directly on the HTTP protocol using REST. You can use Jersey as a REST server/client or roll your own (since you don't want to use JEE, which Jersey is part of).
SIMON is as simple to use as RMI, but with fewer traps in the initial setup. It also has some advantages over RMI. Here is a simple hello-world example:
http://dev.root1.de/projects/simon/wiki/Sample_helloworld110
I take it RMI = Remote Method Invocation ...
You can have a look at XMLRPC, JSONRPC, JMS, or if you want to roll your own, use JSON to POST messages and convert the JSON back to a java object on the other side using GSON (from Google) or setup RabbitMQ and use AMQP to submit and receive messages if you don't want to handle the POSTing yourself, Spring AMQP makes it fairly easy to do this.
Related
The case for event-driven microservices such as Spring Cloud Stream is their asynchronous nature, which I do agree it makes them more scalable
But I have an issue regarding how to code it in a way where I don't lose certain key features that I have access to using synchronous services
In a servlet-based MS, I make full use of servlet context variables and servlet-based Spring autowiring functions
For e.g., I leverage heavily on HTTP headers to carry metadata between microservices without having to impact the payload. But in Spring Cloud Stream using Kafka, Kafka doesn't support message headers of any kind! I lose that immediately if I use SCS. Putting them into the payload causes all sort of changes in my model classes if I define the attributes clearly. Yes, I can use a simple Hashmap to simulate the HTTP header object but it really seems like reinventing the wheel to me.
On the auto-wiring side: I maintain an audit log record per request, which I implement by declaring a request-scoped Hashmap bean and autowiring it into any methods in the Servlet's call stack that needs to append data to the audit log. Basically it's just a global variable to hold some data within a single request. But in SCS, again, I lose that cos bean scopes that leverage on servlets are not available.
So far, there seems to be a lot of trade-offs that I have to make just to make Spring Cloud Stream work for me.
I thought about an alternative approach where I use SCS just to create an entry point but the Source method would just get the event, use a Processor to construct a HTTP request and send the request along to a HTTP endpoint. But, why go through all that trouble then?
Hoping that some more experienced devs would be able to shed some light on how they leverage on SCS.
#feicipet Thanks for the detailed question. let me try to address some of your concerns in the order you have listed them:
+1
+1
I am not sure why you are referring to it as servlet-based instead of Spring-based? Those are features provided by Spring, but read on. . .
Spring Cloud Stream doesn't use Kafka, the end user does while Spring Cloud Stream provides Kafka binder allowing Spring Cloud Stream to integrate with Kafka. Further more, while Kafka indeed did not support headers prior to version 0.11, Spring Cloud Stream always supported and will continue support headers even with Kafka pre-0.11, embedding them in the Message and then extracting them in the consumer side into the proper Message headers completely transparent to the end user. In other words one would assume that Kafka did support headers by simply using Spring Cloud Stream. With Kafka 0.11+ headers are supported natively and we have adjusted to that with the same level of transparency.
So, you don't need to put anything in the payload. Just create an appropriate Message<payload, headers> and SCSt will take care of the rest regardless of the broker (Kafka, Rabbit, Foo etc.).
Yes you do simply due to the fact that as you eluded earlier SCSt promotes an asynchronous and stateless architecture. However, I do not agree that what you are trying to accomplish is un-accomplishable. Rather it is accomplishable the way you are describing, but there are other way to maintain context and I would be more then glad to discuss it as a separate topic.
I would not call them trade-offs, rather difference in the architecture, that has its benefits, but it is a not one-size-fits-all architecture and therefore its viability should be discussed within the context of a concrete use case.
+1. You don't have to separate it as Source and Processor. You can simply create a custom Source app with exposed REST endpoint and custom processing logic. However we are currently working on enhancements i the framework to ensure that you could do the same with the existing starter apps.
Obviously we have touched on many points here and some of them would probably need to be debated further, but I hope this clears up some of your concerns.
Cheers
the technology stack in our company are:
Java, Spring MVC, Spring Boot, Jaxws etc..
and we provide webservices for the client to querying our services.
in terms of securing the SOAP service. some of the webservices uses spring OAuth security and some of them uses the Spring Basic Auth
recently one of the client flooded our server by sending huge amount of request in the short period of time.
we are going to implement something to provent this to happen. ideally a
per client based calling interval. which can recognize the high calling frequency. then ban the client or force the client to wait
before we code this from the scratch, I wonder if there are libraries we can reuse. Spring normally very good at providing solutions for most of the enterprise issues. but so far I have't found any thing. any hint, ideally a working sample. would be great!
EDIT1: ideally we want to implement this instead of fully rely on the HTTP server e.g tomcat or apache to handle this. because our own implementation would offer more fine grained rules, such as how long the interval should be,
what kind of customised message we can return, more important we can implement our own monitoring mechanism, and treating different client with different traffic allowance etc...
We are thinking about having a micro service architecture in our business application. We think about having the communication via ampq. With this researches that i made for that, the question comes up: How to standardise the communication while programming?
For example: If you do some database requests you can use spring-data-jpa that creates for you the code to send those requests.
Isn't there a way to use something like that for AMQP requests if you need an object from another service, something like an AMQPRepositories to have this standardised way?
Does someone has some other ideas or made some experiences with that?
we're developing standard Java SE application and it is necessary to implement some logic on remote server (using Java EE running on OpenShift PaaS). My question is, what is the best way to remote call classes/methods between the SE client and EE application?
My tips:
EJB remote call: however, is the communication encrypted (or possibility to do that)?
Expose EBJs through JAX-RS: looks line nice one, with possibility to use SSL encryption
Thanks for any suggestions.
Title of this question indicates that the Java SE client is in Spring. If the PaaS provided allows, you can even choose Spring. That will help you in long term as the skillset to maintain your application will be small. It'll also improve efficiency.
JAX-RS is features provided by Spring and EJB are almost same.
Assuming you are bound to use EJBs, I'd suggest to go with 'Expose EBJs through JAX-RS'.
Pros -
It avoids tight coupling of client and service. Remote calls will make client aware of EJBs.
In future, you can choose to change your technology from EJB to something else, then client will be minimally impacted.
If you think to write client in any other technology than Java, then it'll be smooth.
Saves time related to JNDI setup
Cons -
Additional time for marshalling and un-marshalling.
Request-response convertes on client and server sides
I have a Java EE application where the model is updated very frequently from various sources. In addition I have a rich client application which triggers some actions via remote EJBs but which should also display the model changes ate least every second.
What is the easiest/ best option for sending the changes from the Java EE application to Java client application? Till now I have the following options:
polling a remote EJB every second from the client
polling a servlet (Is it preferable to use json/ xml instead of java object serialization? Any other serialization?)
websockets (Is it possible to send Java objects here? Or must the result be serialized to Json for for example?)
tcp socket connection (The server would provide a port where the client connects to on startup. Model changes are send via standard object serialization. Is this "allowed" in a Java EE app?)
Option 1 is the easiest one, you can use there asynchronous EJB methods:
SERVER
#Asynchronous
public Future<String> getUpdatedModel() {
//here create blocking process until something interesting happen
return new AsyncResult<String>("model has changed!");
}
CLIENT
Future<String> updatedModel = bean.getUpdatedModel();
while(true){
String response = updatedModel.get();
//process response here
}
Option 2 looks like option 1, but you have to take care of marshaling objects, so don't bother in using plain servlet.
Option 3 looks interesting, as websockets are going to be included in Java EE7 (now you can use opensource comet implementations for servlets). In my opinion it is not designed for communication in enterprise applications, but might be fine for your usecase. There is a plenty of JSON serializers available (e.g. gson), I use that kind of communication between JS and java, and works fine.
Option 4 breaks major Java EE principles (opening your own sockets is forbidden), and I would discourage you to use it.
Option 5 Listen to Xie and use JMS! If you will use JMS topic, you could just send the message when particular event occur, and all connected client will receive the message asynchronously. It is natural Java EE way of solving this kind of problems, with out of box transactions, message redelivery and persistence if nessesary.