I have a remote service and an, object (singleton). When I call the singleton class from UI thread and remote service I get 2 objects. Can anyone help me?
If you have a remote service then you have 2 completely separate processes. Each process has its own virtual machine. Therefore, your singleton class is instantiated once in each process.
If you really need a single then think about whether you really need a remote service. If you can implement your remote service as a local service then that will solve your problem.
If, on the other hand, you really need a single instance that is shared across the 2 separate processes, then you will need to instantiate the singleton only in the remote services process and access it via remote calls from the UI process.
Related
This question is rather broad I'm sure but I believe I don't fully understand how multi-user applications work and I would like some clarification on the subject or an idea of where to look for more info (not sure I know what to search for)
I understand the development aspect, but once you deploy the code to the server, how does it handle multiple users? For example, if I have a singleton class then that class will only ever be instantiated on the server once ... but the class will need to be used by multiple users simultaneously which means that the variables inside the class need to potentially be different for each user, how is this achieved behind the scenes?
Is it just the concept that each different user will access the class on a different thread? and if so, wouldn't that mean the whole application needed to be thread safe?
Let me explain this straight and will start from this point
once you deploy the code to the server, how does it handle multiple users?
----> Yes every web application or enterprise application should be deployed in server, web application on web server like tomcat enterprise applications on WebSphere. Every server will have servlet container with multiple number of threads (by default 200 in tomcat) each input request will be handled by individual thread (so multiple request can execute concurrently)
if I have a singleton class then that class will only ever be instantiated on the server once
---> yes singleton class will have only one instance per server, so multiple threads can access same object concurrently and which may cause data inconsistency, which is developer responsibility to take care of this responsibilities. The main problem with singleton class will be class (instance or static) level variables with setter methods because two threads can access same object concurrently and change the values, In the real time scenario singleton design pattern is used for Connection Pool object
Note Local variables are best in multithreading because every thread has its own stack, and they cannot be access by any other threads.
but the class will need to be used by multiple users simultaneously which means that the variables inside the class need to potentially be different for each user
---> To save request properties into object Models or POJO will comes into picture, these are prototype for every request new object will be created.
I wanna do a service that distributs tasks amongst several servers, which execute those tasks.
To do that, I made use of the Java RMI technology and all works just fine, but it is a mess. I have a big class, which is
mixed with remote methods which are called by the servers to post messages and client methods
to schedule tasks to the service which are called by the client.
I am now trying to find a proper solution to encapsulate the remote methods from the business methods, but struggle as they are thighly coupled. The message implementation (see the example class diagramm) interacts thightly with the private business methods.
This might also include invoking events which the Client class
subscribed. My first thought was the approach with a message handler. But how can the message handler still interact with private methods of the server and invoke events on the service.
I like to ask you if you have any idea for my problem. How can I encapsulte the remote interface and its methods from the non remote methods?
If I understand the problem correctly, you have a big class with three kinds of method:-
Remote methods intended for use by the client, but not by the server;
Remote methods intended for use by the server, but not by the client; and
Local methods not intended to be remote at all.
It seems to me that creating two remote interfaces (one for the client, one for the server) and implementing them both in the big class will do what you want. The client will only see one interface and the methods in it; similarly for the task server.
Is that enough encapsulation? Or did you mean something more?
When I use JNDI to get an object from a remote server, the object can be serialised to the local JVM, this way I am assuming that we can call methods on this object locally without RMI, so why we need RMI?
JNDI is a look-up and directory service. It provides a standardized way to acquire resources by name within some context. Usually it used for acquiring shared resources from an application-server context, but depending on implementation, it can also provide for looking up items in a standardized way that represent remote resources.
RMI is a remote method invocation technology built-in to the Java platform. It allows for calling remote java object methods over a binary protocol. It uses Java's built-in serialization handling to make the remote invocation and parameter passing over the network seem transparent. RMI requires it's own directory/look-up service that or might not be integrated with a given JNDI implementation. (Usually they are not integrated.)
So, with all that in mind, hopefully you can see why your question isn't very clear. You might look-up a remote RMI service via JNDI. You might be able to save (serialize) that remote RMI reference to disk and then reconstruct it to use it again later (although that is probably not a good idea.) But regardless, JNDI and RMI are two different things.
When I use JNDI to get an object from a remote server, the object can be serialised to the local JVM, this way I am assuming that we can call methods on this object locally without RMI, so why we need RMI?
So you can call methods remotely. An object that has been deserialized into your local JVM executes in your JVM. A remote object executes in a remote JVM even though you called it from your local JVM.
I am assuming that we can call methods on this object locally without
RMI
No,It is important to understand that you need two extra objects when you make a remote method invocation. The Stub which runs on the client side and de Skeleton which runs on the server side. These objects performs the necessary low level operations.
When the client invokes a remote method it never call directly the object, instead it uses the Stub object.
Therefore, what you get from JNDI service is the Stub not the remote object.
I'm writing an app which uses MDBs, EJBs and needs ThreadLocal to pass and log a variable across multiple EJBs and Helper classes until the transaction is complete.
The flow is
Starting with MDB onMessage()
-> some business delegate EJBs
-> some helpers
Question:
This app runs within Weblogic and Weblogic re-uses Threads from within it's ThreadPool. So is there a possibility of data corruption across threads? Is the solution to use ThreadLocal.remove() safe enough?
Is there an alternative to ThreadLocal other than passing around the Object as a parameter to all methods?
WebLogic does not reset user set ThreadLocal variables when the thread is returned back to the pool - the user is responsible for managing them. When such threads are reused, its likely they will interfere. You may run into memory leaks since the thread local reference isn't cleaned up. You can safely reset your thread locals prior to returning the thread back to the container. The ThreadLocal.remove() call should clean it up (ensure that its done in a finally block)
Note that if any async or rmi calls are involved, your thread locals will not propagate. You may want to consider the WebLogic WorkArea feature which allows context propagation across threads, clients & servers. More details can be found at http://download.oracle.com/docs/cd/E17904_01/web.1111/e13706/context.htm#i1058690
You can't reliably use a ThreadLocal in the EJB tier. Even if your code seems to 'work' now, what happens if someone deploys one of your beans remotely? From EJB Restrictions:
Why is thread creation and management disallowed?
The EJB specification assigns to the EJB container the responsibility
for managing threads. Allowing enterprise bean instances to create and
manage threads would interfere with the container's ability to control
its components' lifecycle. Thread management is not a business
function, it is an implementation detail, and is typically complicated
and platform-specific. Letting the container manage threads relieves
the enterprise bean developer of dealing with threading issues.
Multithreaded applications are still possible, but control of
multithreading is located in the container, not in the enterprise
bean.
If you need to share state, you should pass it in to the EJB method as a parameter. Is there a reason this approach won't work for you? Another option would be to temporarily dump it into a transaction enlisted database or cache.
#JoseK: though I have not tried what you described in your issue, but here are my thoughts:-
Both MDB and Session beans are thread-safe. It means let us say if there is pool of 10 beans, only 10 requests will be handled simultaneously. Other requests would be queued for their turn. So one running thread local data should not interfere with other thread.
If you confident to use always local EJBs in future also, then I don't really see any issue in using thread local data. Because you are not really creating threads.
Though weblogic provides thread from thread-pool but that thread is given dedicately to each request flow, I don't think its local data should become corrupted ever.
As I said I have not tried myself, what I would try is:-
In MDB layer(your first layer), do Thread.getCurrentThread.setName(name)
and in subsequent layers print thread names like Thread.getCurrentThread.getName)
Perform multiple runs with different size of ejb pool, thread pool. Give a different thread name to each request flow. Try running multiple requests same time. And see if you ever get thread name mixed.
5.Having said above, to keep things simpler and furture remote EJB support, I would also pass CallingContext Interface to each layer.
Is it recommended to use ThreadLocal to store a Thread Context?
I am building a backend server application where there are typical services that I need to run.
Note: We are not building this over a SOA architecture.
Before the start of each service I need to give it a state which has some Service Contex which is variable map to work up on. This variable map is shared when services are running parallelly.
Now for example a service needs to check weather it has to be halted or timed-out based on some thread related parameters.
Question: Is it a good approach to keep the thread context inside thread local and then building api's over service context to access parameters over these variables.
This would help me to hide the complex behavior and it wouldn't open up my internal things.
Thanks,
Aditya
It looks like your server application framework ought to provide you with the means to implement this functionality in a simpler way - unless you are implementing your own framework.
Now for example a service needs to check weather it has to be halted or timed-out based on some thread related parameters.
An EJB container provides this kind of functionality. EJBs also provides a session context and the means to ensure that the context can be restored if execution is transferred between threads (by passivation + activation).
You can use ThreadLocal quite freely but you must define your thread model cleanly (see if you have any control on the thread creation)... also keep in mind that assuring the state stored in the ThreadLocal might not what you expect, if you are relying on any clean-up code.
Also: do use (cant stress more) WeakReference for anything that your code is not directly responsible.