in our project we have a need for distributed synchronization where a given thread's lock state has to be synchronized on multiple nodes in a cluster so that the threads running on other nodes can wait on this locked object. I know Java does not do this across JVMs. I don't have the leverage to introduce a new 3rd party product (like Terracotta) at this stage in our project. I was wondering if Weblogic (11g) has some inbuilt facility that allows me to achieve this...
You can use SingletonService. It is a cluster-wide singleton in WebLogic. You should bind it to a JNDI name in activate method and then make lookup and call from other beans. Remember to implement your singleton service object as a plain RMI object not EJB, so make an interface extending Remote and add RemoteExceptions to methods.
For this to work you must configure WebLogic cluster service migration and migration basis.
Here is a complete guide for implementing and configuring the service.
Related
I'm new to Java EE and got confused about EJB.
As I understand #remote EJBs are using RMI and JNDI for communication.
Before EJB3.0 beans needed to implement Remote interface through EJBHome interface - that way I understand how RMI was used.
But now I only need to put #remote annotation, which can be substituted by properties in ejb-jar.xml.
So, the question is: how is it possible to use JNDI without Serializible interface and RMI without Remote interface?
Please correct me if some of my assumptions are wrong.
EJB3 still uses RMI underneath except the application container will take care of generating and using RMI stubs and remote interfaces automatically for you and map them to your EJB3 classes.
You are still required to use Serializible in certain cases. See this:
Clustered Session Beans (SLSB & SFSB)
First of all, clustered EJB3
SLSBs or SFSBs do not need to implement Serializable. In fact, it's
recommended that they don't. In the case of clustered SLSBs, no state
replication occurs, so their instance variables do not even need to be
Serializable. With clustered SFSBs though, the same serialization
rules used for SFSB passivation apply to SFSB state replication. In
other words, all non-transient instance variables that are not
references to beans, sessions contexts or user transactions must be
serializable, or null at replication time. For further information on
the SFSB passivation (and by extension replication because in both
cases the SFSB bean context needs to be serialized), please check
section 4.2.1 of the EJB3 core specification.
Clustered Entity Beans
These only need to be marked Serializable if
the clustered entity instances are to be passed by value as a detached
object (e.g., through a remote interface). Otherwise, there's no need
to mark them as Serializable.
EJB uses RMI, but it's not exactly equal to RMI. The container generates classes and interfaces at runtime that conform to the RMI spec, and hide them from you. This is why in a EJB project your remote client usually needs to include in its classpath a bunch of libraries specific to the container.
In this regard, EJB 2.0 was more transparent to the fact that it uses RMI under the hood, and thus, more complicated.
On most of applications servers, J2EE Ejb specification forbids creating threads "by hand", since these resources should be managed by the server.
But is there any way to get threads from Tomcat, Glassfish, Jboss etc.; thus access their ThreadPool?
You can use the commonj WorkManager. It was a proposal by IBM and BEA to provide a standard means to accomplish this task (access to container managed threads).
Although it was not included in the actual specification, there are implementations available for most containers.
Use in Weblogic
Use in WebSphere
Implementation for Tomcat, JBOSS and maybe others
Spring integration
The legal way to get threads from container is using JCA (Java Connector Architecture). The component you implement using this technology is called "resource adapter" and is packaged as rar file.
The implementation is pretty verbose but not too complicated in simple cases. So, good luck.
I've seen at least one utility class for getting ahold of Tomcat's threadpool, but it's not wise to go this route. Those threads are created to service your EJB or Servlet's requests, not for you to support the EJB or Servlet. Each one you take up is just another thread that won't be available to service requests to the container.
You could probably just throw in a static ThreadPool and use a static initializer to get around the EJB spec on this one, but you'd obviously have to make sure the thread code works well otherwise it could really bork your EJB.
We've got a Spring based web application that makes use of Hibernate to load/store its entities to the underlying database.
Since it's a backend application we not only want to allow our UI but also 3rd party tools to manually initiate DB transactions. That's why the callers need to
Call a StartTransaction method and in return get an ID that they can refer to
Do all DB relevant calls (e. g. creating, modifying, deleting) by referring to this ID to make clear which operations belong to the started transaction
Call the CommitTransaction method to signal to our backend that the transaction can be committed now (or in the negative case RollbackTransaction will be called)
So keeping in mind, that all database handling will be done internally by the Java persistence annotations, how can we open the transaction management to our UI that behaves like a 3rd party application that has no direct access to the backend entities but deals with data transfer objects only?
From the Spring Reference: Programmatic transaction management
I think this can be done but would be a royal pain to implement/verify. You would basically require a transaction manager which is not bounded by "per-thread-transaction" definition but spans across multiple invocations for the same client.
JTA + Stateful session beans might be something you would want to have a look at.
Why don't you build services around your 'back end application' for example a SOAP interface or a REST interface.
With this strategy you can manage your transaction in the backend
Is there a way to find all nodes belonging to the cluster of the web-application? I know on JBoss i can use HAServiceMBeanSupport to get information about all nodes(hostname, IP-adress), but how can I achieve something similar on Tomcat, WebSpere, Glassfish, Oracle AS, Jetty, WebLogic?
(Best would be an interface which works for all of them)
There is no standard drop-in solution for what you are asking for.
Technically it can be achieved in many ways - both within java ecosystem and outside e.g. Jgroups cluster forming, Zookeeper or simple Redis or other K/V server where each server instance would register upon startup and subscribe for changes in the cluster group.
The support and required effort will vary though. The general approach would be to use some startup hook e.g. Servlet container initialization or EJB #Startup #Singleton to contact the topology discovery service(your redis server for example), provide the info about your instance and query info about the other instances already active. If you need leader election, you can use many algorithms, e.g. first come-first serve basis, or based on voting. Then you need to subscribe and actively listen for changes in topology, and possibly provide some kind of health metric - e.g. periodically let others know, that your instance is still active
On a general note, can you elaborate why would your app need to have the knowledge about other instances of the same type? Do you need Master election or HA cluster-wide singleton functionality? The best practice for building stable scalable solutions is to keep the app stateless and unaware of the scaling details.
Functions, that need to be only executed in sequence or on a single node at the time, could be extracted into a dedicated service e.g. batch job service, scheduler service etc.
Most JEE server vendors offer some custom solution for this e.g. JBoss HASingleton service, or HA singleton deployment(app will always run only on a single instance in the cluster) which also takes care of failover.
As far as I know, it depends of the capabilities of your Applicationserver.
There is no "standardway" to do this.
You can try the following:
The class ServletContextListener has two methods. You can calculate the hostname and the IP-Adress(es) within the create method, and delete the node in the destroy method.
This way has problems during a VM-crash the destroy-method will not be called, for instance.
EDIT:
Does your software need a Database? If so, all clusternodes have to use the same database instance. If your app is deployed without a cluster it uses a "private" database. You need a shared DB:
Table: NODES
HOST | IP
as1.cluster | < ip >
as2.cluster | < ip2 >
If only onne line inserted to that DB, there is no cluster.
But this table may be corrupted, if a node crashes and does not remove its entry from this Table.
When you use javax.xml.ws.Endpoint.publish to handle incoming restful/soap requests, will it generate a thread for each request? or will I have handle threads myself?
I've been trying to work this out for a couple of days now. The documentation hints on threads, but there is nothing specific about this.
Doc says:
An Executor may be set on the endpoint in order to gain better control
over the threads used to dispatch incoming requests. For instance,
thread pooling with certain parameters can be enabled by creating a
ThreadPoolExecutor and registering it with the endpoint.
For me that looks like it handles threads, but you will have no control over them, so adding a ThreadPoolExecutor to execute the threads, you will have a pool of threads you can work with. Is this right?
Examining section 5.2.7 of the JavaTM API for XML-Based Web Services specification (JAX-WS) seems to indicate so, although it looks like there is some room for implementation specific behavior. To really know what is going on you'd have to investigate the JAX-WS implementation you are using and the particular deployment environment. I'd imagine the behavior might be different depending upon whether the service is deployed within a Servlet container or in a standalone process. The control that you do have over the threads is limited to providing a specific ThreadPoolExecutor implementation. Section 5.2.7 states:
5.2.7 Executor
Endpoint instances can be configured with a java.util.concurrent.Executor. The executor will then be used to dispatch any incoming requests to the application. The setExecutor and getExecutor methods of Endpoint can be used to modify and retrieve the executor configured for a service.
<> Conformance (Use of Executor): If an executor object is successfully set on an Endpoint via the setExecutor method, then an implementation MUST use it to dispatch incoming requests upon publication of the Endpoint by means of the publish(String address) method. If publishing is carried out using the publish(Object serverContext)) method, an implementation MAY use the specified executor or another one specific to the server context being used.
<> Conformance (Default Executor): If an executor has not been set on an Endpoint, an implementation MUST use its own executor, a java.util.concurrent.ThreadPoolExecutor or analogous mechanism, to dispatch incoming requests.
Also, section 5.2.2 references 5.2.7 near the end of the section:
5.2.2 Publishing
...
An Endpoint will be typically invoked to serve concurrent requests, so its implementor should be written so as to support multiple threads. The synchronized keyword may be used as usual to control access to critical sections of code. For finer control over the threads used to dispatch incoming requests, an application can directly set the executor to be used, as described in section 5.2.7.
I realize this probably doesn't answer your question exactly, but hopefully it points you in a direction that you can get the answer you are looking for.
An Executor needs to be set in order to make an Endpoint multi-threaded. A simple multi-threaded Executor would be the fixed thread pool Executor.
endpoint.setExecutor(Executors.newFixedThreadPool(4));
This will allow your WebService to accept 4 connections simultaneously. But make sure your Service is thread safe.
I could not find and answer to this in the official doco, but after playing around with it and reading 'Java Web Services: Up and Running', it seems like it does not generate threads for each connections. So the service is blocked until it's done with one request, then a new request is handled.
Endpoint.publish(Url, ServiceImplObj) publishes a webservice at a given url. The no. of threads assigned for request handling truly is under control of the jvm because this is a light weight deployment which is handled by jvm itself.
For better clarification you can print the current thread name at service side and you can see that the service threads are being assigned from a thread pool which is managed by jvm.
[pool-1-thread-1]: Response[57]:
[pool-1-thread-5]: Response[58]:
[pool-1-thread-4]: Response[59]:
[pool-1-thread-3]: Response[60]:
[pool-1-thread-6]: Response[61]:
[pool-1-thread-6]: Response[62]:
I have used jdk1.6.0_35
xjc -version
xjc version "JAXB 2.1.10 in JDK 6"
JavaTM Architecture for XML Binding(JAXB) Reference Implementation, (build JAXB
2.1.10 in JDK 6)