How to connect SpringBoot JMX beans with Jolokia? - java

I'm using #EnableMBeanExport in a SpringBoot application to make my beans with #ManagedResource be available to the JMX server. This works fine in simple local processes with VisualVM.
I'm now trying to add Jolokia into the mix, so I can reference those beans remotely with a REST service instead of setting up a remote RMI connection, which is annoying.
The Jolokia doc page at https://jolokia.org/reference/html/jmx.html says to use the following:
MBeanServer jolokiaServer = JolokiaMBeanServerUtil.getJolokiaMBeanServer();
However, there doesn't appear to be a "JolokiaMBeanServerUtil" class in Jolokia.
Update:
Ok, I found the artifact with the class, but the solution doesn't appear to be as simple as just declaring a bean with this value. When I attempt to call a jmx method with a jolokia url, I get an exception like the following:
java.lang.IllegalArgumentException: Invalid object name. Key properties cannot be empty
at org.jolokia.request.JmxRequestFactory.createGetRequest(JmxRequestFactory.java:99)
at org.jolokia.http.HttpRequestHandler.handleGetRequest(HttpRequestHandler.java:79)
at org.jolokia.http.AgentServlet$4.handleRequest(AgentServlet.java:470)

Related

Spring boot Cloud Embedding Config Server to get properties from Git repo for each request

I am using Spring Cloud Embedding Config Server to get the configuration from Git while server startup. Its working fine. Below is my config.
bootstrap.properties
spring.application.name= "credentialInfo"
spring.cloud.config.server.bootstrap= "true"
spring.cloud.config.server.git.uri= "https://11111#bitbucket.global.company.com/scm/~11111/spring-cloud-config.git"
spring.cloud.config.server.git.username= "aaaa"
spring.cloud.config.server.git.password= "bbbb"
Now I have to get the properties from Git repo for each request with username and password collected from Customers.How can I achieve this ..?
Normally client application get properties from git though config server when startup and when call to "actuator/refresh" endpoint.
I'm that the requirement as you state its doesn't work well with Spring Boot.
When configurations are read (no matter from where, including the configuration service) they are used to configure spring beans during the startup.
For example, if you have a configuration of, say, db host, this configuration is supposed to be used by bean responsible for database connectivity (DataSource)
The point is that by the time that Application Context starts, beans are already configured.
Its true that some beans having refreashable scope define a custom logic to get "re-initialized" as a consequence of calling /refresh endpoint, but this is not what you're asking for (at least as far as I understood)
Instead you say, that the client does something during the application startup and this action should lead to beans change. This is potentially a very expensive operation and I don't think you should go in this direction. Usually beans are not re-created during runtime (of scope singleton, and the chances are that most of the beans are of this scope)

Not able to access JNDI Url context from Spring boot application deployed in WAS Liberty server

I have deployed an spring boot web application in WAS Liberty server (WebSphere Application Server Version 8.5.5.9 Liberty Profile).
I have a JNDI url entry added in server.xml which is given below but one of my class in api is not able to access it.
<jndiURLEntry jndiName="url/SSOService" value="http://ssoserver.dev.intranet/SSOService/SSOFacade" />
I found one weird thing in Liberty is that whenever I add java:comp/env/ to any of the JNDI entry , application is not able to pick it and getting javax.naming.NameNotFoundException:
I fixed the datasource issue by not adding the prefix, but the above URL is used in only of the api which is not in my control.
So how can we enable java:com/env prefix in Websphere Liberty server ?
or is there any alternative available to make this working ?
When you define a JNDI URL entry in the following way:
<jndiURLEntry jndiName="url/SSOService" value="..."/>
It will make the java.net.URL available literally at the url/SSOService name (i.e. no sort of java: prefix). Looking up a JNDI entry from this location is known as a "direct lookup", because you are looking something up that was defined directly in server configuration.
If you want to register this in the java:comp/env/ namespace, you must define a "resource reference", which will create a binding from the server-defined entry to a java:comp/env/ entry. A resource reference can be defined annotatively or via web.xml.
Here is how you can define an annotative resource reference:
#Resource(lookup="url/SSOService", name="url/SSOServiceRef")
URL ssoServiceURL;
In this example, we're saying:
Perform a direct lookup of url/SSOService
Bind that object to java:comp/env/url/SSOServiceRef

Externalise REST endpoint in Websphere Application Server

I have to consume a REST endpoint from the Utility class written in Java. Utility class is deployed in application server as part of my EAR. The REST resource end point will vary depends on environment like (DEV, TEST, PRE-PROD and PROD). So, I want to externalize the end point and should be able to change it without code change.
The normal way to do this is to configure a URL in JNDI, and do a JNDI lookup for the URL and configure the resource in each environment as it needs to be.
In the Websphere console under Resources there is a place for "URL" which would seem to be place you would want to put this and then do the lookup in code (or wire in the lookup via Spring or your personal preference).

Spring problems integrating ActiveMQ inside Liferay

I'm modifying a Maven-based Liferay portlet (6.1.1) that uses Service Layer.
My needs are to add an ActiveMQ listener to the portlet (for communication with external products).
I'm trying to use integrated spring engine (3.0.7) to instance the listener.
So, to start, inside ext-sping.xml (auto managed by Liferay) I defined the following beans:
- a connection factory: org.apache.activemq.ActiveMQConnectionFactory
- a caching connection factory (org.springframework.jms.connection.CachingConnectionFactory) with targetConnectionFactory reference to previous bean.
At deploying time the error I get is:
Cannot convert value of type [org.apache.activemq.ActiveMQConnectionFactory] to
required type [javax.jms.ConnectionFactory] for property
'targetConnectionFactory': no matching editors or conversion strategy found
Obviusly org.apache.activemq.ActiveMQConnectionFactory implements javax.jms.ConnectionFactory, infact if I try to set the value by code, the deploy is done succesfully.
In my pom.xml I try to add a depenency both to activemq-core (just activemq) or activemq-all (contains also javax.jms package), but without success.
How it is possible?
Thank you
Possibly a classloader problem - the classloader loading the CachingConnectionFactory is resolving to a different javax.jms.ConnectionFactory to the one loading the ActiveMQ factory.
Run with -verbose on the command line to see which jar(s) classes are being loaded from.

question on tomcat and jmx

What is the MBeanServerFactory.findMBeanServer(null); exactly doing?
Returns a list of all registered MBeanServers? Registered where?
I am asking because I have the following problem.
I have a java web app deployed in Tomcat using a service wrapper.
I have custom connector implementations in my server.xml that use ManagedBeans (spring enabled).
If I start the app via the service wrapper all is ok.
If I start the web app through Tomcat directly it seems that the deployment breaks.
All I see in the logs is that the connector does a
MBeanServerFactory.findMBeanServer(null);
and then tries to invoke the bean beanServer.invoke(name, operationName, null, null);
The result is a InstanceNotFoundException.
It seems that the managed beans are not loaded in case I do not use a service wrapper? Is my understanding correct? Any input on how to debug this issue is
highly welcome!
The javadoc says that when you pass null, it returns the servers registered in the current JVM. If you are using JSW, then you cannot use null as JSW forks the VM as a separate process. This is why you see the InstanceNotFoundException.

Categories