I am looking for a way to integrate external services (like active directory and DB access, web service calls) in a non (or incomplete) Java EE environment such as Tomcat. In a full Java EE server I would (probably) implement a resource adapter (JCA) however in the current project everything runs in a tomcat (v.7.X). This means that many apects like concurrency, transactions, state etc. are not handled by a Java EE container.
It is a stateless setting and the folks told me that there will be some kind of transaction handling (details are due, JTA?). There will be several tomcats in a clustered environment. The number of users is in 3-4 digits range.
My questions are:
How and when should I initialize external services access? (Use a singleton or a factory etc.?)
Should I use a third party connection pool for database access? (like Hikari or the tomcat internal one)
How to deal with concurrency? (synchronized blocks, using volatile?)
Related
I just spent the day building and rebuilding docker images of my app with different variations of JVM command line options -Dcom.sun.management.jmxremote....
So I can get JMX authentication to work which was one step forward, but then anybody in my organisation could login and execute JMX commands.
But it seems to me that I have to rely on putting usernames and passwords in text files in my docker containers (or accessible to them) if I want to restrict authorization to a small group of users.
Isn't there another out-of-the-box way to monitor memory and threads and manipulate loggers or connection pools etc in production?
The official docs Monitoring and Management Using JMX Technology are not encouraging.
I thought microservices architecture might have a new approach but I can't find it on the web or on stackoverflow.
I investigated coding up a routine to launch the JMX server internally with custom authorization to use the Krb5LoginModule to access AD groups following JMX Authentication - Role Based MBean Operations and Support for Kerberos Authentication/Authorization on JMX Client/Server running on Java 6
I even dredged up a long-since vanished Oracle blog post on the subject at the waybackmachine: Authentication and Authorization in JMX RMI connectors
Now at the end of the day it's obvious that I have to keep it simpler than this and go with the out-of-the-box solution, but that is so primitive and looks like it hasn't been improved since Java 1.6.
Is JMX just a basic mechanism to allow EJB containers to do JMX, which of course being gargantuan EJB containers, they have their own JMX connectors that pre-authorize everything.
Isn't there something that will allow me to implement AD groups for authorization in a multi-user environment without writing my own JMX security module?
Jolokia is uncharted territory for me, and after having read the documentation, I'm still not sure if it'll work with the scenario I have in mind.
Setup:
Tomcat application server (version ranges from 6.x to 7.x), usually on a Windows platform, occasionally a flavour of Linux.
Deployed third-party Java web application (SAP BusinessObjects) with JMX monitoring enabled (accessible through RMI).
Possible gotcha's:
The Java web application to be monitored is commercial and closed source, so modifications are not possible. The only thing that can be changed is the JMX port number
The JMX endpoint is a custom one, thus not the default jmxrmi endpoint.
The JMX connection requires authentication.
Goal:
What I'd like to do is to deploy the Jolokia WAR file onto the Tomcat server and then configure it so that I can read the MBean attributes from the other web application.
I would code the client myself using Python (version 3) and the Requests HTTP library.
I've been reading through the Jolokia documentation (again, I'm a complete newbie at this point), but can't figure out if this would be possible or not (as I can't seem to find where to enter the JMX/RMI url or the authentication information).
Questions:
Can I use the WAR agent for this setup?
If not, can you please explain why (so I can understand, not because I don't believe you). Also, is there another agent that's more suited for this scenario?
If yes, can you point me in the right direction how to configure the Jolokia to the web application to connect to?
First of all, Jolokia by passes the JSR-160 connector stuff completely, so there is no need for any JMX/RMI authentication. The whole purpose of Jolokia is to provide a bridge over HTTP/JSON to the internal JMX subsystem. Depending on the agent, you can secure Jolokia quite easily. For the WAR agent, securing is the same as for any Java EE web app: Setup some roles and users for tomcat (e.g. in tomcat-users.xml) and reference the role in the security contstraints within the jolokia.war's /WEB-INF/web.xml.
To your questions:
Yes, you can. If you don't have any specific authentication needs, simply drop the jolokia.war into tomcat's /webapps directory. I suggest to try this first before adding security. For deinstalling the agent, simply remove the war.
As an alternative, you could also use the JVM agent, which opens an own HTTP server on an extra port (default: 8778). More on this in the reference manual
There is no need for a dedicated connection to the web app since MBeans are registered globally and are accesible from anywhere in the JVM. A webapp should of course select carefully the management information it exposes. So, there is no extra step needed and you can access the MBeans for the WEB app directly (except when it does something unusual with Java security, but I don't think so).
To test the installation, simply connect to the Tomcat with your browser and the context /jolokia (e.g. "http://localhost:8080/jolokia"). You should see the version information about the agent itself.
The next step would be to explore the JMX namespace, either with the browser (and operation "list" like in http://localhost:8080/jolokia/list , but that's tedious) or with a client like j4psh or hawt.io. Hopefully you will find the MBeans of your webapp you are looking for.
Is it possible to create a client that accesses an EJB3 bean, with the client having no dependence on a vendor JAR or configuration? We currently need to support scenarios where our service is deployed on a WebSphere or JBoss server, and the client is deployed as an application either on a WAS or JBoss, or is running as a standalone app.
I used to be able to do to this with EJB2.x beans, I just needed to create stubs using RMIC.
But with EJB3, If I'm connecting to WebSphere I have to include thinclient JARs, plus I have to pre-generate the stubs using WAS tools. For JBoss I have to use jboss-client.jar.
No, this is not possible. This has been made explicit in section 10 of the EJB 3.2 specification:
This chapter describes the interoperability support for accessing an
enterprise bean through the EJB 2.1 remote client view from clients
distributed over a network, and the distributed interoperability
requirements for invocations on enterprise beans from remote clients
that are Java Platform, Enterprise Edition (Java EE) components.
Distributed Interoperability is not defined for the EJB 3.x remote client view.
Also note section 10.5.5:
System value classes are serializable value classes implementing the
javax.ejb.Handle, javax.ejb.HomeHandle, javax.ejb.EJBMetaData,
java.util.Enumeration,java.util.Collection, and java.util.Iterator
interfaces. These value classes are provided by the EJB container
vendor. They must be provided in the form of a JAR file by the
container hosting the referenced bean. For interoperability scenarios,
if a referencing component would use such system value classes at
runtime, the Deployer must ensure that these system value classes
provided by the container hosting the referenced bean are available to
the referencing component. This may be done, for example, by including
these system value classes in the classpath of the referencing
container, or by deploying the system value classes with the
referencing component’s application by providing them to the
deployment tool.
For WebSphere Application Server, the EJB thinclient contains these system value classes as well as the IBM JNDI implementation that uses CosNaming. In theory, this thinclient is not needed if you don't need the system value classes and your client JVM has its own ORB with an implementation of CosNaming.
Short answer: No, it's not possible, as a client needs three things:
The interface classes.
The client libraries of the server AS (yes, sadly)
A configuration telling the client the server address/jndi lookup path (qa, prod etc.)
If your client is running on the same product (let's say JBoss to JBoss communication), you will not be in need of client libraries and just be able to do a remote lookup. If you have a mix of client/server application servers this will make things complicated, as you will have to run client libraries of one product in another server product.
Speaking of standalone applications running as clients, I'd just build and provide 1 heavy client jar/lib containing not only the interface classes, but also the client libs of both servers. Then providing a small helper class that returns the correct InitialContext created and based either on JBoss or Websphere depending on a flag in the client configuration.
I know this last idea ain't a clean solution, though might even work in a different AS product running as "client".
I do understand that using the same tomcat instance for a number of web applications has some risks (e.g. if one web application crashes tomcat it will terminate the other web applications as well.). The benefit is of course cost effectiveness since one server is enough and having all the web applications in one place makes it very easy to administrate.
Are there any industry guidelines on how a good setup with multiple web applications on tomcat should look like?
Pros
One JVM to monitor
Common libraries can be shared (sometimes risky)
Cons
Common HTTP thread pool all applications are using (you can, however, configure several connectors with different thread pools)
One malfunctioning application can take down the whole server
Restarting one application requires restarting all of them (if not using hot-deployment)
You are right that hosting of multiple we applications on one application server / web container (either Tomcat or other) has benefits.
You mentioned the robustness issue when one application may cause failure of another. But let's simplify this: even if you have only one application you still want 24*7 availability. To achieve this goal people typically run more than one instance of application server with identical application on each one and load balancer in the enterence to the site. The same is relevant for several web applications. Just run N (2 as minimum) application servers with identical set of web applications deployed and load balancer. You will probably need a kind of watchdog that restarts server if it failed or if it stopped responding etc.
In some cases kind of clustering is required. But it is other story.
As the title suggests, this is in relation to Java EE and Glassfish in particular.
From what i've learned the application client is executed in some application client that has the ability to talk to glassfish. But there seems to be limitations to this regarding annotations.
Can someone give me an example of the difference in connecting to a glassfish application server from the two different application types?
What is the benefit of the application client approach, and what approach is the most commonly used when developing application clients for Java EE?
The code (work you need to do) associated with connecting to the app server in either case is not really all that hard... but it is covered in different docs.
These are the instructions on how to access an EJB from a stand-alone java application.
These are the instructions for using an app client to access an EJB from a Java EE 6 Application Client with GlassFish v3: http://docs.sun.com/app/docs/doc/820-7695/beakt?l=en&a=view
Accessing an EJB from an application client gives you access to more of Java EE services 'automagically' than if you were working with the EJB 'directly'. You can cobble together access to some of these services in the stand-alone case, but the burden shifts onto the application developer/deployer to make that access work.
Creating a stand-alone application that accesses an EJB will seem easy, in the short term, and many folks will invest in that strategy. If they deploy their client application onto a large number of machines, the burden associated with a cobbled together service access strategy can become a burden.
Deploying an application client that uses the application client container is not free either. The advantage is the fact that you have the support of your app server vendor to overcome deployment issues.
If you are using GlassFish (v2.1,v2.1.1 or v3), you can also take advantage of Java Web Start support, which simplifies client application deployment a lot.
An application client is actually run in a container and has full access to Java EE resources defined on your server in the same way that a Servlet or EJB does. This would typically be used for some type of admin client, not a user application. Here is one explanation.
In addition to the Java EE Application Client, there is also the concept of a Thin Client, which allows access to some Java EE resources as well, but not as easily as the App Client. It usually involves using JNDI lookup with absolute names as JNDI references are not available. A typical case for this would be a standalone producer/consumer of JMS messages. It is basically a lighter weight option of the full App Client.
If you are simply creating a user application, you will most likely want to either use a Thin Client model, or a plain old application that simply consumes services from your Java EE app via servlet or web service calls.