JMX enabling my Application using Jetty as embedded server - java

I have a java server application that would like to provide Http
interface to for administrative tasks such as monitoring and
configuring it at run-time and such.
I have some idea that JMX would provide me with a neat standard
interface that if I implement, I would provide a nice standard
management interface that ALL types of management console applications
can use to administor my Server application.
I am wondering if Jetty has a part to play in all of this running
in-process (embedded) into my java application?
what do you think is a best way of managing/monitoring my java application using a web interface?
Appreciate your help

We added a jmx rest interface option in jetty some time ago that might be useful here.
http://webtide.intalio.com/2011/05/jetty-jmx-webservice/
It could easily be pulled from for an admin like interface for management or presentation purposes.

JMX would allow you to expose configuration points for your application. This is required if you desire a programmatic/automated way of configuring your application. Using JMX to configure application is not desirable for a naive users. It is not very likely that they would know how to use JMX. Instead a graphical console would appeal to them. They can simply see what they need to configure, refer any reference material or help and just do it.
It is desirable that you have both the options; a web console and also the JMX way for programmatic access.
Secondly, you dont need a any third party server to JMX-enable your application. You simply create an instance of MBeanServer and it will host your mbeans.

Related

Accepting request from specific ip in Spring Boot

I referred this tutorial to restrict certain ip in jboss and Spring Boot application.
http://www.mastertheboss.com/jboss-web/jbosswebserver/how-to-restrict-access-to-jboss-web-application-by-ip-or-host
But the tutorial is not complete. Where should I place those codes? Are there any other methods to do that?
If any one know any other methods please mention that here. Thanks in advance.
IMO the Valves mentioned in tutorial are the ways to customize tomcat embedded into the Jboss application. Note that this tutorial is really old - from 2014, probably JBoss has changed since then.
I remember back that times JBoss indeed included Tomcat inside to handle the web requests, so probably there was some kind of server.xml of tomcat.
Now, there are other ways:
Place the application behind some proxy that would restrict the access. Probably its the best approach if your environment supports that.
Use filters inside the application. You can create a web filter and register it in spring boot application regardless whether its a Jar with embedded server or WAR that you're planning to deploy on JBoss. This can be really flexible but on the other hand it includes some java coding and will consume some resources of your application. You can use this approach if you don't have spring security in your application and you don't want to introduce one, otherwise read (3).
Kind of paraphrase on 2 but used with spring security, that has the filtering facility built in: here is how you can do that. Note that besides the actual Java code used for implementation, 3 and 2 are pretty similar.
I'd approach this problem in the following way:
If the IP where connections are accepted is subject to change, I'd configure reverse proxy like nginx. This would mean you don't have to redeploy or restart your application if the IP address changes. Please see this guide for details on how to configure nginx: https://docs.nginx.com/nginx/admin-guide/security-controls/controlling-access-proxied-tcp/
Otherwise I'd refer to this article: https://access.redhat.com/solutions/18412 describing the following configuration in WEB-INF/jboss-web.xml:
<valve>
<class-name>org.apache.catalina.valves.RemoteAddrValve</class-name>
<param>
<param-name>allow</param-name>
<param-value>127.0.0.1,127.0.0.2</param-value>
</param>
</valve>
</jboss-web>
To me this concern should be handled on infrastructure level, not in application container. I would suggest to look into AWS Security Groups or equivalent concepts in other cloud providers.
If you are running it in private cloud/bare metal, you should investigate to restrict it on transport layer your infrastructure provides. There should be some possibility to configure firewall rules.

Is remote JMX security out-of-the-box really so basic or am I missing something?

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?

Use Jolokia to monitor JMX endpoint of webapp on same Tomcat server

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.

How to invoke a method remotely?

I have two java projects. From project1 I have to call a method of project2. Both the projects are developed using the core java concepts and running seperately. As I know that in this case I will have to use any techniques that remotely invokes the methods(Am I correct?), like RMI, WebServices, JMS etc. I have to very frequently call the method of project2 from project1. What could be the best possible way to achieve this.
Thanks
Are your projects deployed to an application server or servlet container?
You can use web services to expose the method from Project 2. This would be standards based and would allow non-Java projects also in the future to access your service if required.
If it works for you, try to implement it in an asynchronous mode for better performance. Web services allow for asynchronous mode of invocation as well. However, for this, your Project 1 would also need expose a callback method.
EDIT:
I had come across that in Java 6, you can deploy web services outside of servlet container as well. Below link can help.
Standalone web services in Java SE 6
However not sure if this can be used in production environments.
RMI is used in Client-Server architecture. There will be a server program that will implement your interface extending Remote and it will have definitions or calls to other methods at server and it will bind an object. Then you will need a client program that will look up for that object and using that object, it will call methods on Server.
So if your projects are running as Client-Server then you can try this thing.
Next thing you are talking about is WebServices. WebServices provide access to some code written at server to its clients over a network via specific protocols. In this your code will be running on a server and you will access it from your client using Web Service.
Now it is up to you what kind of architecture you are following for your projects and which method is more useful and suitable for your scenerio.

Access JMX agents from non-Java clients

For some integration projects I would like to query JMX agents from non-Java clients.
I found two options so far, ws-jmx-connector (Soap based) and mx4j and its JMX HTTP adaptor which returns XML document responses. The JSR 262 based ws-jmx-connector seems to be no longer in active development. I have not tried MX4J so I do not know if it is possible to use the HTTP adaptor with the standard JMX implementation in the J2SE.
Are there other software projects which can help to connect non-Java clients with JMX agents, using open standard protocols?
Update: meanwhile I found this project, a "Restful JMX Adaptor". It is also described in the article RESTful Access to JMX Instrumentation, Via URI-fication of MBean Attributes
I recommend Jolokia, which is a full featured JSON/HTTP adapter for JMX. It has several client libs, i.e. jmx4perl, which allows for programatic JMX access from within perl. For Java and Javascript there are client bindings, too. More are in the pipeline (Scala, Groovy, Python). The installation is dead easy, for a Java EE container it is as simple as deploying a standard Java EE war. Other agents (OSGi, Mule, JVM6) are available, too.
Jolokia is a agent based and implies that I install a server and agents. What I am after is a lightweight pure command line, non-java based, non-agent based solution to call JMX/RMI interface.
Let it be a C-code application or perl or python whatever as long as it is fast.

Categories