Let me exaplain you the complete situation currently I am stuck with in.
We are developing very much complex application in GWT and Hibernate, we are trying to host client and server code on different servers because of client's requirement. Now, I am able to achieve so using JNDI.
Here comes the tricky part, client need to have that application on different Platform also, database would be same and methods would be the same, lets say iPhone / .Net version of our application. we don't want to generate Server code again because it's gonna be the same for all.
I have tried for WebServices wrapper on the top of my server code but because of complexity of architecture and Classes dependencies I am not able to do so. For example, Lets consider below code.
class Document {
List<User>;
List<AccessLevels>;
}
Document class have list of users, list of accesslevels and lot more list of other classes and that other classes have more lists. Some important server methods takes Class (Document or any other) as input and return some other class in output. And we shouldn't use complex architecture in WebServices.
So, I need to stick with JNDI. Now, I don't know how can I access JNDI call to any other application ???
Please suggest ways to overcome this situation. I am open for technology changes that means JNDI / WebServices or any other technology that servers me well.
Thanking You,
Regards,
I have never seen JNDI used as a mechanism for request/response inter-process communication. I don't believe that this will be a productive line of attack.
You believe that Web Services are inappropriate when the payloads are complex. I disagree, I have seen many successful projects using quite large payloads, with many nested classes. Trivial example: Customers with Orders with Order Lines with Products with ... and so on.
It is clearly desirable to keep payload sizes small, there are serialization and network costs, big objects will be more expensive. But it's by far preferable to have one big request than lot's of little one. A "busy" interface will not perform well across a network.
I suspect that the one problem you may have is that certain of the server-side classes are not pure data, they refer to classes that only make sense on the server, you don't want those classes in you client.
I this case you need to build an "adapter" layer. This is dull work, but no matter what Inter-process communication technique you use you will need to do it. You need what I refer to as Data Transfer Objects (DTOs) - these represent payloads that are understood in client, using only classes reasonable for the client, and which the server can consume and create.
Lets suppose that you use technology XXX (JNDI, Web Service, direct socket call, JMS)
Client --- sends Document DTO --XXX---> Adapter transform DTO to server's Document
and similarly in reverse. My claim is that no matter what XXX is chosen you have the same problem, you need the client to work with "cut-down" objects that reveal none of the server's implementation details.
The adapter has responsibility for creating and understanding DTOs.
I find that working with RESTful Web Services using JAX/RS is very easy once you have a set of DTOs it's the work of minutes to create Web Services.
Related
I have a Liferay instance running on a URL like example.org/app. This instance does have a REST API that would normally be running under example.org/app/o/restpath.
The way the server running this instance is that the frontend is accessible without restrictions from the outside, however the REST API is only accessible from the inside the network under a URL like example.org/rest.
I need to make sure that it is impossible to access the REST API with example.org/app. I should also be impossible to access the frontend with example.org/rest. Does anybody have any suggestions?
There are tons of ways of doing that, the best one will depend on your stack, preferences and abilities.
A reverse proxy is the first that comes to mind, bearing in mind that is is normally better if your app has control of who can access it. So a wrapper or a filter checking who is accessing would help. But even then, is the filter to be put on the main application or on your module? That is an evaluation that needs to come from you.
You can also combine the proxy strategy, with a filter, just in case one day you are tuning up your proxy and let something through. You can also decide change your proxy server too..
Or your company already have a proxy that enables traffic going out, and would be easier if that proxy was to have access...
Your servlet contained might also be able to provide such control, so you do not actually need a proxy.
Although I would feel more comfortable if that kind of feature was in the application layer itself, like a wrapper for your component and that wrapper provides the service, a filter, or even a method in in the entry-point, while the others are just extra and to reduce load.
Some companies have networks devices that go up several layers of the network stack, those have lots of potential to help here too, IDS would be able to provide alarms, triggers and such...
As it stands, one would need more information to help you more, even in what you mean by "ensure" ( how far this assurance need to go, like are you thinking about passwords, certificates, IDS, or a simple approach like the mentioned ones ), but I guess that covers it.
I have a XML webservice application that consists of several parts. There is a common entry servlet that delegates to different internal webservices based on the request parameters.
Now I wonder which solution might be better:
to have any of those services running within a single application? So, one application serves all?
or split them into microservices, where each servlet app is responsible for only one single purpose/brand?
Example: lets assume we have a common car service that serves content for all cars of a brand. Each of them might have completely different logic.
Some brands might have periodic data imports.
Some brands might get data from additional an external webservice.
Some brands might have a database cache, etc.
/my/rest/car/AUDI/details?id=123
/my/rest/car/BMW/details?id=456
...
Most of those webservices are nearly independent. Though they are currently contained within a single application, as they all serve "car content".
Now I'm rethinking if it could make sense having the common /my/rest/car/{brand} webservice servlet in a main war file. And then create a new war file for each of the brands. Each of them would offer its own XML webservice, and the common servlet would delegate and join them.
Of course, this might result in a bit overhead, as the xml request and response has to be exchanged locally between those services.
But as an advantage, I could more easily maintain and restart each service individually without downtime of the others, and would have less side effects refactoring and extending a part. Eg if there is only one data import change for BWM.
So, what is your experience in splitting large applications like this? One serves all, or single services?
I am working on an application in Java on Google App Engine where we have a concept of RPC, but when should we ideally make use of RPC? The same functionality that I am doing with RPC could be implemented even without it. So in what scenario should ideally RPC be designed.....?
You typically use RPC (or similar) when you need to access a service that is external to the current application.
If you are simply trying to call a method that is part of this application (i.e. in this application's address space) then it is unnecessary ... and wasteful to use RPC.
... when should we ideally make use of RPC?
When you need it, and not when you don't need it.
The same functionality that I am doing with RPC could be implemented even without it.
If the same functionality can be implemented without RPC, then it sounds like you don't need it.
So in what scenario should ideally RPC be designed.....?
When it is needed (see above).
A more instructive answer would be scenarios where there are good reasons to implement different functions of a "system" in different programs running in different address spaces and (typically) on different machines. Good reasons might include such things as:
insulating one part of a system from another
implementing different parts of a system in different languages
interfacing with legacy systems
interfacing with subsystems provided by third party suppliers; e.g. databases
making use of computing resources of other machines
providing redundancy
and so on.
It sounds like you don't need RPC in your application.
RPC is used whenever you need to access data from resources on the server that are not available on the client. For example web services, databases, etc.
RPC is designed for request/response. i.e. you have a self contained request to a service and you expect a response (return value or a success/failure status)
You can use it anywhere you might use a method call except the object you are calling is not local to the current process.
I am developing a stand-alone java client application that connects to a Glassfish v3 application for JPA/EJB facade style transactions. In other words, my client application do not connect directly to the database to CRUD, but it transfers JPA objets using EJB stateless sessions.
I have scenarios where this client application will be used in an external network connected with a VPN over Internet with a client connection of 512kbp/DSL, and a simple query takes so much time, I'm seeing the traffic graph and when I merge a entity in the client application I see megabytes of traffic (I couldn't believe how a purchase order entity could weight more than 1 mb).
I have LAZY fetch in almost every many-to-many relationship, but I have a lot of many-to-one relationships between entities (but this is the great advantage of JPA!).
Could I do something to accelerate the the speed of transactions between JPA/EJB server and the remote java client?
Thank you in advance.
How much data do you really transfer? Maybe the purchase order you're sending has a product, which has a model, which has a supplier, which has a set of models... and so on...
You could try serializing the object you're sending to the server into a file (using the standard ObjectOutputStrem) and check how big the file is.
I'm seeing the traffic graph and when
I merge a entity in the client
application I see megabytes of traffic
(I couldn't believe how a purchase
order entity could weight more than 1
mb).
RMI-IIOP is a bit more verbose than plain RMI. In my experience, it doesn't work well when transferring large graphs.
So far I remember (but maybe things changed in the meantime), when you transfer an lazy loaded entity, the parts that haven't been loaded yet are sent as-is (the proxy is serialized), which means you can not access them on the client because lazy loading won't work if there is no session anymore. Are you eagerly loading the entity before sending it back to the client?
Could I do something to accelerate the
the speed of transactions between
JPA/EJB server and the remote java
client?
But the crux of the problem is that you are in a scenario where you need to think about a strategy to transfer data. You must design you application is a way that you don't send large graphs; this concern must be addressed in the design of your app. Then you can decide to still send JPA entities or rely on Data Transfer Object (DTO).
You might also consider using an extended persistence context with a stateful session bean, this way I think an entity on the client side can still be loaded lazy. But I never used this personally and don't know if it works well or not.
If I understand your architecture correctly you have:
Client(works with disconnected Entities)
----RMI/IIOP--->
Server(SLSB, using entitiy manager, JPA persistence)
----JDBC------->
Database
In effect your SLSBs are expressing their interface in terms of the JPA Objects, your DTOs are the JPA objects. I see two possible scenarios:
your client needs only a subset of the data in your JPA objects, and you are transfering more than you acually need. For example you might only need an employee's name and you send his entire life history.
you are traversing more of the relationship treee than you intend
My feeling is that you should first determine exactly what you are getting in the client. Should be pretty easy to add some trace statements to see exactly what data you have.
Possibly by tweaking the lazy loading etc, you can then control the behaviour.
My expectation is that you may need to define client-specific "subset" DTOs and have your SLSB act more as a facade, sending only the subset data. It's more work, but you have fine control over what's in the interface.
Architecturally, fine tuning a remote interface is quite a reasonable thing to need to do.
Could I do something to accelerate the the speed of transactions between JPA/EJB server and the remote java client?
You can't accelerate things. However, you can transfer less (only the required part or lighter objects).
Currently, I only know a way of doing RPC for POJOs in Java, and is with the very complex EJB/JBoss solution.
Is there any better way of providing a similar functionality with a thiner layer (within or without a Java EE container), using RMI or something that can serialize and send full blown objects over the wire?
I'm not currently interested in HTTP/JSON serialization BTW.
EDIT: For clarification: I'm trying to replace an old EJB 2.1/JBoss 4 solution with something more easy to manage at the container level. I need to have entire control over the database(planning to use iBATIS which would allow me to use fairly complex SQL very easily), but the only things I want to keep over the wire are:
Invocation of lookup/data modification methods (automagic serialization goes here).
Transparent session control (authentication/authorization). I still have to see how to accomplish this.
Both items have to work as a whole, of course. No access should be granted to users without credentials.
Because I'm not very fond of writing webapps, I plan to build a GUI (Swing or SWT) that would only manage POJOs, do some reporting and invoke methods from the container. I want the serialization to be as easy as possible.
As is nearly always the case, Spring comes to the rescue. From the reference documentation, you will want to read Chapter 17. Remoting and web services using Spring.
There are several methods to choose from. The beauty of Spring is that all your interfaces and implementations are vanilla POJOs. The wiring into RMI or whatever is handled by Spring. You can:
Export services using RMI:
probably the simplest approach;
Use HTTP invoker: if remote access is an issue, this might be better for firewalls, etc than pure RMI; or
Use Web Services, in which case I would favour JAX-WS over JAX-RPC.
Spring has the additional benefit in that it can do the wiring for both the server and the client, easily and transparently.
Personally I would choose either (2) or (3). HTTP is network friendly. It's easy to deploy in a Web container. Jetty's long-lived connections give you the option over server push (effectively) over HTTP.
All of these methods allow complex objects to be sent across the wire but they are subtly different in this regard. You need to consider if your server and client are going to be distributed separately and whether it's an issue if you change the interface that you need to redistribute the class files. Or you can use a customized serialization solution (even XML) to avoid this. But that has issues as well.
Using a Web container will allow you to easily plug-in Spring Security, which can be a bit daunting at first just because there are so many options. Also, HttpSession can be used to provide state information between requests.
Simple RPC is exactly what RMI was built for. If you make a serializable interface, you can call methods on one app from another app.
If you only need value objects then just ensure the POJOs implement Serializable and write the objects across sockets (using ObjectOutputStream). On the receiving end read the objects using ObjectInputStream. The receiving end has to have a compatible version of the POJO (see serialVersionUID).
Hessian/Burlap 'protocol-ize this: http://hessian.caucho.com/ and http://www.caucho.com/resin-3.0/protocols/burlap.xtp
You could try XStream (http://x-stream.github.io/) over REST. Easy to apply on e pre-existing set of pojos.
Can you give some further information as to what you're trying to achieve, since you're not interested in rest/json ?