Related
I want to exchange data between two applications JEE6/JSF2.0 and i'm looking for the best solution. I thought of the below solutions :
by using a JSON file.
by using XML file.
by using GSON file.
by using Remote interface (EJB 3.0).
For you, what's the best solution to use ?
edit : This two applications will be always running on the same network (but can not be on the same JVM)
I want to provide an alternative to David's answer, as I feel that there are some drawbacks to RMI that he underplayed.
This is a Java specific technology. If a third server needs to be introduced and it is a Microsoft Reporting Services server for example, then it cannot talk in the same language.
RMI is an OLD technology and doesn't particularly look well on a CV. Web services are the future. Experienced RMI developers are more uncommon than experienced web service developers.
Cumbersome and heavy framework
A better solution in my opinion would be to use SOAP XML based web services. Here are some advantages to this approach:
Universal acceptance in nearly any development framework. No matter the technology, nearly all have helpful libraries for interacting with web services.
Java has good support for object serialization into XML. This means objects can be quickly serialized into a SOAP XML request, sent to the other server, and deserialized back into a Java object by the other application server for processing.
A service layer can give you the decoupling interface between the two applications just as RMI can.
I hope you reconsider the use of SOAP XML based web services in your application.
There's two options really as you yourself stated.
Using RMI to connect to a EJB or using a webservice and communicating by JSON/XML etc...
From my experience RMI can be favorable if your applicaitons are on the same network, if not then you might get problems with firewalls etc and be forced to tunnel the RMI using HTTPS... which pretty much makes the RMI calls webservice calls.
If your on two different machines then webservices are nice as they dont cause as much trouble with firewalls. Also as they use the HTTP protocol you dont have to worry about the data being transfered.
These examples are kinda generalised but should give you some insight.
GSON vs XML vs JSON is a completely different subject... Non is superiour to the other, and all are fairly easily read by the human eye.
UPDATE
From what I've understod you wont have to worry about firewalls and such, I would recommend using RMI. It usually results in cleaner code and somewhat better performance.
Since I have seen both in action, I can make a comparison between the two technologies, EJB and WebServices. I can confirm that EJB is way more efficient, has support of transactions (including distributed transactions, if that is your requirement), exception handling, and binary streaming out of the box. In terms of performance EJB may exceed SOAP by a factor of 5 times in speed, and REST for about 3 times.
However, EJB is not an integration technology. In fact, it has never thought to do so. The biggest flaw of EJB is that it is very coupled to the Java Platform. Therefore, both endpoints must be written in Java and should use the same Java EE version.
Another problem is that EJB is not a protocol per se, so the implementations from two containers/vendors is probably different. If you need to access a remote EJB from JBoss AS on an Oracle WebLogic server, you must bring JBoss EJB client implementation with you.
Another big problem related to integration with EJB is a lack of data exchange format. Since it uses Java Serialized objects for communication, the data types must be shared on both ends. If you create a new exception type on the server that is classified as an Application Exception, if the client who consumes this service triggers the exception, his code will break. Note that, in this case the remote API was not violated, but another unknown type was introduced.
And, of course, by depending solely on the class type as an exchange format, you are giving the programmers opportunity for doing very stupid things. If you have many different teams in large projects using EJB as integration technology using different versions of Java EE, prepare yourself to experience uttermost pain. I've seem a programmer including a JPA entity on the client, who was annotated with named queries, the table which was accessing, its columns, etc, essentially giving away all the database layout to the service consumer. But it can get even worse. I've already seem a programmer returning a data structure that belonged to a dependency, namely Eclipselink 1.0. However, if you access this from a JBoss server, Eclipselink is also a JPA implementation technology, which conflicts with JBoss' hibernate. So, now you have to include Eclipselink jar in your JBoss APP classpath and configure the container for not loading JPA related packages, which otherwise will break your application completely. Even so, it can get WORSE than before: some other service you need to connect had also the bright idea of using the same datastructure, but now from Eclipselink 1.1.1, that has a different implementation, but the same class signature. Now you are in a very bad situation.
The bottom line: NEVER, EVER, use EJB as an integration technology. Use SOAP using a contract-first approach, where you define a canonical data model for the application, mapping java datastructures to a XML exchange format that can be used by any client, be it written in any language or using different stacks. Or use REST implementing a resource based, using HATEOAS principles. These days I rarely seem a reason for using EJB at all, since CDI is now on the market, support many features that EJB does and does not include any RPC related technology.
I have a couple of web services running on JBoss 5.1.0 GA with JBossWs native stack (shipped with JBoss 5.1.0 GA binary)
These web services are simple POJO services. Many of the WebMethods exposed by the services are of Complex Object type (I call these Complex types as DTO's) and a lot of custom defined exceptions. These DTO's are also bundled in a jar file, so that they can be used at the Client end as well.
I started creating a client using Eclipse (which I understand is using wsconsume to generate the client stub) and I saw that the utility would generate the DTO's from the WSDL and I could not find any way of enforcing the utility to use the DTO & exception classes provided in the jar file.
I had earlier asked a question on this on SO and could not find any answers.
From reading of various resources on wsconsume and generating client stub using eclipse (which would use JBossWS) i have now started to believe that what I am trying to achieve might not actually be possible using wsconsume.
My question is:
Is there a better way to create a client stub which would use the DTO classes from the jar files. I am open on changing the Client generation mechanism and move to axis or any other library for Client generation if that is possible. It would also be ideal if an ant task can be created for Client stub generation.
PS: My knowledge on web services is very limited and if I am being stupid with my question here, please pardon me for that.
Why do you want to use Data Transfer Objects in Your Web Service ? Is that necessary? Because If you use such objects, those web services can be use only in Java I think. That is a interoperability issue. So If you can avoid those kind of objects that will be a good practice.
In short, how do you transfer semantic data between client and server with GWT and which frameworks do you use? Read on for more details that I've thought about.
For example, using GWT 2.2.0 features like the RequestFactory will bring the constraint to have java beans transferred while the semantic resources are represented as triples and a resource can have a varying set of properties. So the RequestFactory itself cannot be shaped to transfer semantic-driven data easily.
A way to do that would be to use RequestFactory with beans that represent triples. Such bean would have 3 properties: subject, predicate, object. These beans will be transferred to client which will know to query, change their properties and then send them to server. This approach will however need a custom implementation(there are no GWT-based frameworks to represent semantic data on client-side, from what I've searched so far) and that could prove buggy or unoptimized. I've seen this approach in this project: http://code.google.com/p/gwt-odb-ui/ - it used GWT-RPC and implements some classes that represent semantic resources. However, I think it's in an incipient stage so I'm reluctant to copy their model.
Also, I've found that Restlets is a framework that supports the semantic web approach to applications. However, there is no documentation or an example on how to use Restlets with Semantic Web and perhaps with GWT. Also, Restlets is also supporting GWT. Does anyone know if this is a viable solution or not?
Thank you!
Restlet should work quite well for you. It has a GWT edition able to automatically serialize your triple beans. In addition, it also comes with an org.restlet.ext.rdf extension, including a Link class similar to your triple bean idea.
For further documentation, I would suggest the "Restlet in Action" book which covers GWT and the semantic web from a Restlet and REST point of view.
I am trying to figure out if I should migrate my gwt-rpc calls to the new GWT2.1 RequestFactory cals.
Google documentation vaguely mentions that RequestFactory is a better client-server communication method for "data-oriented services"
What I can distill from the documentation is that there is a new Proxy class that simplifies the communication (you don't pass back and forth the actual entity but just the proxy, so it is lighter weight and easier to manage)
Is that the whole point or am I missing something else in the big picture?
The big difference between GWT RPC and RequestFactory is that the RPC system is "RPC-by-concrete-type" while RequestFactory is "RPC-by-interface".
RPC is more convenient to get started with, because you write fewer lines of code and use the same class on both the client and the server. You might create a Person class with a bunch of getters and setters and maybe some simple business logic for further slicing-and-dicing of the data in the Person object. This works quite well until you wind up wanting to have server-specific, non-GWT-compatible, code inside your class. Because the RPC system is based on having the same concrete type on both the client and the server, you can hit a complexity wall based on the capabilities of your GWT client.
To get around the use of incompatible code, many users wind up creating a peer PersonDTO that shadows the real Person object used on the server. The PersonDTO just has a subset of the getters and setters of the server-side, "domain", Person object. Now you have to write code that marshalls data between the Person and PersonDTO object and all other object types that you want to pass to the client.
RequestFactory starts off by assuming that your domain objects aren't going to be GWT-compatible. You simply declare the properties that should be read and written by the client code in a Proxy interface, and the RequestFactory server components take care of marshaling the data and invoking your service methods. For applications that have a well-defined concept of "Entities" or "Objects with identity and version", the EntityProxy type is used to expose the persistent identity semantics of your data to the client code. Simple objects are mapped using the ValueProxy type.
With RequestFactory, you pay an up-front startup cost to accommodate more complicated systems than GWT RPC easily supports. RequestFactory's ServiceLayer provides significantly more hooks to customize its behavior by adding ServiceLayerDecorator instances.
I went through a transition from RPC to RF. First I have to say my experience is limited in that, I used as many EntityProxies as 0.
Advantages of GWT RPC:
It's very easy to set-up, understand and to LEARN!
Same class-based objects are used on the client and on the server.
This approach saves tons of code.
Ideal, when the same model objects (and POJOS) are used on either client and server, POJOs == MODEL OBJECTs == DTOs
Easy to move stuff from the server to client.
Easy to share implementation of common logic between client and server (this can turn out as a critical disadvantage when you need a different logic).
Disadvatages of GWT RPC:
Impossible to have different implementation of some methods for server and client, e.g. you might need to use different logging framework on client and server, or different equals method.
REALLY BAD implementation that is not further extensible: most of the server functionality is implemented as static methods on a RPC class. THAT REALLY SUCKS.
e.g. It is impossible to add server-side errors obfuscation
Some security XSS concerns that are not quite elegantly solvable, see docs (I am not sure whether this is more elegant for RequestFactory)
Disadvantages of RequestFactory:
REALLY HARD to understand from the official doc, what's the merit of it! It starts right at completely misleading term PROXIES - these are actually DTOs of RF that are created by RF automatically. Proxies are defined by interfaces, e.g. #ProxyFor(Journal.class). IDE checks if there exists corresponding methods on Journal. So much for the mapping.
RF will not do much for you in terms of commonalities of client and server because
On the client you need to convert "PROXIES" to your client domain objects and vice-versa. This is completely ridiculous. It could be done in few lines of code declaratively, but there's NO SUPPORT FOR THAT! If only we could map our domain objects to proxies more elegantly, something like JavaScript method JSON.stringify(..,,) is MISSING in RF toolbox.
Don't forget you are also responsible for setting transferable properties of your domain objects to proxies, and so on recursively.
POOR ERROR HANDLING on the server and - Stack-traces are omitted by default on the server and you re getting empty useless exceptions on the client. Even when I set custom error handler, I was not able to get to low-level stack traces! Terrible.
Some minor bugs in IDE support and elsewhere. I filed two bug requests that were accepted. Not an Einstein was needed to figure out that those were actually bugs.
DOCUMENTATION SUCKS. As I mentioned proxies should be better explained, the term is MISLEADING. For the basic common problems, that I was solving, DOCS IS USELESS. Another example of misunderstanding from the DOC is connection of JPA annotations to RF. It looks from the succinct docs that they kinda play together, and yes, there is a corresponding question on StackOverflow. I recommend to forget any JPA 'connection' before understanding RF.
Advantages of RequestFactory
Excellent forum support.
IDE support is pretty good (but is not an advantage in contrast with RPC)
Flexibility of your client and server implementation (loose coupling)
Fancy stuff, connected to EntityProxies, beyond simple DTOs - caching, partial updates, very useful for mobile.
You can use ValueProxies as the simplest replacement for DTOs (but you have to do all not so fancy conversions yourself).
Support for Bean Validations JSR-303.
Considering other disadvantages of GWT in general:
Impossible to run integration tests (GWT client code + remote server) with provided JUnit support <= all JSNI has to be mocked (e.g. localStorage), SOP is an issue.
No support for testing setup - headless browser + remote server <= no simple headless testing for GWT, SOP.
Yes, it is possible to run selenium integration tests (but that's not what I want)
JSNI is very powerful, but at those shiny talks they give at conferences they do not talk much about that writing JSNI codes has some also some rules. Again, figuring out how to write a simple callback was a task worth of true researcher.
In summary, transition from GWT RPC to RequestFactory is far from WIN-WIN situation,
when RPC mostly fits your needs. You end up writing tons conversions from client domain objects to proxies and vice-versa. But you get some flexibility and robustness of your solution. And support on the forum is excellent, on Saturday as well!
Considering all advantages and disadvantages I just mentioned, it pays really well to think in advance whether any of these approaches actually brings improvement to your solution and to your development set-up without big trade-offs.
I find the idea of creating Proxy classes for all my entities quite annoying. My Hibernate/JPA pojos are auto-generated from the database model. Why do I now need to create a second mirror of those for RPC? We have a nice "estivation" framework that takes care of "de-hibernating" the pojos.
Also, the idea of defining service interfaces that don't quite implement the server side service as a java contract but do implement the methods - sounds very J2EE 1.x/2.x to me.
Unlike RequestFactory which has poor error handling and testing capabilities (since it processes most of the stuff under the hood of GWT), RPC allows you to use a more service oriented approach. RequestFactory implements a more modern dependency injection styled approach that can provide a useful approach if you need to invoke complex polymorphic data structures. When using RPC your data structures will need to be more flat, as this will allow your marshaling utilities to translate between your json/xml and java models. Using RPC also allows you to implement more robust architecture, as quoted from the gwt dev section on Google's website.
"Simple Client/Server Deployment
The first and most straightforward way to think of service definitions is to treat them as your application's entire back end. From this perspective, client-side code is your "front end" and all service code that runs on the server is "back end." If you take this approach, your service implementations would tend to be more general-purpose APIs that are not tightly coupled to one specific application. Your service definitions would likely directly access databases through JDBC or Hibernate or even files in the server's file system. For many applications, this view is appropriate, and it can be very efficient because it reduces the number of tiers.
Multi-Tier Deployment
In more complex, multi-tiered architectures, your GWT service definitions could simply be lightweight gateways that call through to back-end server environments such as J2EE servers. From this perspective, your services can be viewed as the "server half" of your application's user interface. Instead of being general-purpose, services are created for the specific needs of your user interface. Your services become the "front end" to the "back end" classes that are written by stitching together calls to a more general-purpose back-end layer of services, implemented, for example, as a cluster of J2EE servers. This kind of architecture is appropriate if you require your back-end services to run on a physically separate computer from your HTTP server."
Also note that setting up a single RequestFactory service requires creating around 6 or so java classes where as RPC only requires 3. More code == more errors and complexity in my book.
RequestFactory also has a little bit more overhead during the request processing, as it has to marshal serialization between the data proxies and actual java models. This added interface adds extra processing cycles which can really add up in an enterprise or production environment.
I also do not believe that RequestFactory services are serialization like RPC services.
All in all after using both for some time now, i always go with RPC as its more lightweight, easier to test and debug, and faster then using a RequestFactory. Although RequestFactory might be more elegant and extensible then its RPC counter part. The added complexity does not make it a better tool necessary.
My opinion is that the best architecture is to use two web apps , one client and one server. The server is a simple lightweight generic java webapp that uses the servlet.jar library. The client is GWT. You make RESTful request via GWT-RPC into the server side of the client web application. The server side of the client is just a pass though to apache http client which uses a persistant tunnel into the request handler you have running as a single servlet in your server servlet web application. The servlet web application should contain your database application layer (hibernate, cayenne, sql etc..) This allows you to fully divorce the database object models from the actual client providing a much more extensible and robust way to develop and unit test your application. Granted it requires a tad bit of initial setup time, but in the end allows you to create a dynamic request factory sitting outside of GWT. This allows you to leverage the best of both worlds. Not to mention being able to test and make changes to your server side without having to have the gwt client compiled or build.
I think it's really helpful if you have a heavy pojo on the client side, for example if you use Hibernate or JPA entities.
We adopted another solution, using a Django style persistence framework with very light entities.
The only caveat I would put in is that RequestFactory uses the binary data transport (deRPC maybe?) and not the normal GWT-RPC.
This only matters if you are doing heavy testing with SyncProxy, Jmeter, Fiddler, or any similar tool that can read/evaluate the contents of the HTTP request/response (like GWT-RPC), but would be more challenging with deRPC or RequestFactory.
We have have a very large implementation of GWT-RPC in our project.
Actually we have 50 Service interfaces with many methods each, and we have problems with the size of TypeSerializers generated by the compiler that turns our JS code huge.
So we are analizing to move towards RequestFactory.
I have been read for a couple of days digging into the web and trying to find what other people are doing.
The most important drawback I saw, and maybe I could be wrong, is that with RequestFactory your are no longer in control of the communication between your Server Domain objects and your client ones.
What we need is apply the load / save pattern in a controlled way. I mean, for example client receive the whole object graph of objects belonging to a specific transaction, do his updates and them send the whole back to the server. The server will be responsible for doing validation, compare old with new values and do persistance. If 2 users from different sites gets the same transaction and do some updates, the resulting transaction shouldn't be the merged one. One of the updates should fail in my scenario.
I don't see that RequestFactory helps supporting this kind of processing.
Regards
Daniel
Is it fair to say that when considering a limited MIS application, say with 10-20 CRUD'able business objects, and each with ~1-10 properties, that really it's down to personal preference which route to go with?
If so, then perhaps projecting how your application is going to scale could be the key in choosing your route GWT RPC or RequestFactory:
My application is expected to stay with that relatively limited number of entities but will massively increase in terms of their numbers. 10-20 objects * 100,000 records.
My application is going to increase significantly in the breadth of entities but the relative numbers involved of each will remain low. 5000 objects * 100 records.
My application is expected to stay with that relatively limited number of entities AND will stay in relatively low numbers of e.g. 10-20 objects * 100 records
In my case, I'm at the very starting point of trying to make this decision. Further complicated by having to change UI client side architecture as well as making the transport choice. My previous (significantly) large scale GWT UI used the Hmvc4Gwt library, which has been superseded by the GWT MVP facilities.
I mean, really, what is the point of SOAP?
Web services have been around for a while, and for a while it seemed that the terms 'SOAP' and 'Web service' were largely interchangeable. However SOAP always seemed unwieldy and massively overcomplicated to me.
Then REST came along, and suddenly web services made sense.
As Joel Spolsky says, give a programmer a REST URL, and they can start playing with the service right away, figuring it out.
SOAP is obfuscated behind WSDLs and massively verbose XML, and despite being web based, you can't do anything as simple as access a SOAP service with a web browser.
So the essence of my question is:
Are there any good reasons to ever choose SOAP over REST?
Are you working with SOAP now? Would it be better if the interface was REST?
Am I wrong?
As Joel Spolsky says, give a programmer a REST URL, and they can start playing with the service right away, figuring it out.
Whereas if the service had a well specified, machine readable contract, then the programmer wouldn't have to waste any time figuring it out.
(not that WSDL/SOAP is necessarily an example of good implementation of a well specified contract, but that was the point of WSDL)
Originally, SOAP was a simple protocol which allowed you to add a header to a message, and had a standardized mapping of object instances to XML structures. Putting the handling metadata in the message simplified the client code, and meant you could very simply persist and queue messages.
I never needed the header processing details when I built SOAP services back in 2001. This was pre-WSDL, and it was then normal to use GET for getting information and queries (no different to most applications which claim to be REST; REST has more in terms of using hyperlinks for service discovery) and POST with a SOAP payload to perform actions. Those actions which created resources would return the URL of the created resource to the client, and the client could then GET the resource. I think it's the fact that WSDL made it easy to think only in terms of RPC rather than actions which create resources which made SOAP lose the plot.
The way I see it, SOAP might be more "flexible", but as a result it's just way too complicated (you mentioned the WSDL, which is always a stumbling block to me personally).
I get REST. It's simple. The only downside I might see is that you are limiting yourself to those 4 basic actions against a single resource, which might not exactly fit the way you view your data.
The topic is well-discussed in Why is soap considered to be thick.
While doing some research to understand some of the answers here (especially John Saunders') I found this post http://harmful.cat-v.org/software/xml/soap/simple
SOAP is more insane than I thought...
The point of WSDL was auto-discovery. The idea was that you wouldn't have to write client code, it would be auto-generated.
BTW. next step beyond WSDL are Semantic Web Services.
If you don't need the features of the WS-* series of protocols; if you don't need self-describing services; if your service cannot be completely described as resources, as defined by the HTTP protocol; if you don't like having to author XML for every interaction with the service, and parse it afterwards; then you need SOAP.
Otherwise, sure, use REST.
There's been some question about the value of a self-describing service. My imagination fails me when it comes to imagining how anyone could fail to understand this. That's on me. Still, I have to think that anyone who has ever used a service much more complicated than "Hello, world" would know why it is valuable to have someone else write the code that accepts parameters, creates the XML to send to the service, sends it, receives the response, then turns that back into objects.
Now, I suppose this might not be necessary when using a RESTful service; at least not with a RESTful service that does not process complex objects. Even with a relatively simple service like http://www.earthtools.org/webservices.htm (which I've used as an example of calling a RESTful service), one benefits from understanding the structure of the returned data. Even the above service provides an XML Schema - it unfortunately doesn't describe the entire response. Given that schema one still has to manually process the XML, or else use a tool to produce serializable classes from the schema.
All of this happens for you when the service is described in a WSDL, and you use a tool like "Add Service Reference" in Visual Studio, or the svcutil.exe program, or I-forget-what-the-command-is-in-Eclipse.
If you want examples, start with the EarthTools services, and go on to any other services with more complicated messaging.
BTW, another thing that requires self-description is description of the messaging patterns and protocols supported by the service. Perhaps that's not required when the only choices are HTTP verbs over HTTP or HTTPS. Life gets more complicated if you're using WS-Security and friends.
I find that SOAP fits in most appropriately when there is a high probability that a service will be consumed by corporate off the shelf (COTS) software. Because of the well specified contract employed by SOAP/WSDL most COTS packages have built in functionality for consuming such services. This can make it easy for BPM/workflow tools etc. to simply consume defined services without customization. Beyond that service use case REST tends to be my goto web service implementation for applications.
Well it appears now that the WSI agree that SOAP no longer has a point as they have announced they will cease to exist as an independent entity.
Interesting article about the announcement and some commentary here: http://blogs.computerworlduk.com/simon-says/2010/11/the-end-of-the-road-for-web-services/index.htm
Edited to be completely accurate in response to John Saunders.
I think SOAP appeals to the Java and .net crowd who may be more familiar with the old CORBA and COM and less familiar with internet technologies.
REST also has one major drawback: there is very little guidance on how to actually implement such a system. You will find significant variations on how many of the public RESTful APIs have been designed. In fact many violate key aspects of REST (such as using GET for manipulation or POST for retrieval) and there are disagreements over fundamental usage (POST/GET vs POST/GET/PUT/DELETE).
Am I wrong?
"You're not wrong, Walter, you're just... :)"
Are there any good reasons to ever choose SOAP over REST?
SOAP, to my understanding adheres to a contract, thus can be type checked.
SOAP is a lightweight XML based structured protocol specification to be used in the implementation of services . It is used for exchanging
structured information in a decentralized, distributed environment. SOAP uses XML technologies for exchanging of information over any transport layer protocol.
It is independent of any particular programming model and other implementation specific semantics. Learn More about XML
SOAP Messaging Framework
XML-based messaging framework that is
1) Extensible : Simplicity remains one of SOAP's primary design goals. SOAP defines a communication framework that allows for features such as security, routing, and
reliability to be added later as layered extensions
2) Inter operable : SOAP can be used over any transport protocol such as TCP, HTTP, SMTP. SOAP provides an explicit binding today for HTTP.
3) Independent : SOAP allows for any programming model and is not tied to Remote procedure call(RPC). SOAP defines a model for processing individual, one-way messages.
SOAP also allows for any number of message exchange patterns (MEPs) .Learn more about SOAP