question on tomcat and jmx - java

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.

Related

Configuring cxf service listing in karaf

It is a web service deployed on Apache Karaf using camel-cxf. I am able to see the cxf service listing in URL localhost:8181/cxf which has some rest and soap services deployed on it.
The problem is it is returning the service listing whenever any request comes with keyword "services". For example the url http://localhost:8181/abcd/services returns cxf service listing page instead of processing the actual request.
I got to know from http://cxf.apache.org/docs/jaxrs-services-description.html that its is because of the default value of service-list-path of CXFServet is services.
Here is my Question. If I want to override this, I should set this property in etc/org.apache.cxf.osgi.cfg. This cfg file is not present under etc folder in my karaf. What are the steps to be taken if I am creating this property file manually? What features I need to install? Or creating this cfg is sufficient ?
Appreciate your help !
There should be no extra installation requirements, just create a new file etc/org.apache.cxf.osgi.cfg.
There are three settings you may be interested in:
org.apache.cxf.servlet.context = /mycxf
org.apache.cxf.servlet.service-list-path = /myservices
org.apache.cxf.servlet.hide-service-list-page = false
Where the default URL for the CXF service listing is usually like http://localhost:8181/cxf/services, with the changes above the URL would become http://localhost:8181/mycxf/myservices
If you change from false (default value) to true, then your services will be hidden and you will instead get a page stating No service was found.
Because these are initialisation settings you need to shut down Karaf for the changes to apply.
I see several points here --
The CXF framework is installed by default in karaf under the context-path /cxf.
/cxf/services can be considered as a CXF internal app that displays the list of services deployed in CXF. I don't think you can configure the name "services" here (and why would you change that?)
the "url-pattern in web.xml" you speak of (if I understand correctly) determines the context path of your servlet/application. You can specify this is camel like this:
<cxf:rsServer id="secureRsServer" address="https://0.0.0.0:8182/my/path/"
serviceClass="....">
(for the RS Server, probably same for the WS server).

Call glassfish ejb from stand-alone application

So I have a simple ejb (#stateless) deployed on a glassfish 3.1 server.
I want to call it from a standalone application.
It's working great if I add the gf-client.jar into my run configuration.
But how can I do if I do not have that file (the server is in another machine) ?
I tried using
<dependency>
<groupId>org.glassfish.common</groupId>
<artifactId>glassfish-naming</artifactId>
<version>LATEST</version>
</dependency>
But I have
Exception in thread "main" javax.naming.NameNotFoundException: java:global
at com.sun.enterprise.naming.impl.TransientContext.resolveContext(TransientContext.java:252)
at com.sun.enterprise.naming.impl.TransientContext.lookup(TransientContext.java:171)
at com.sun.enterprise.naming.impl.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:58)
at com.sun.enterprise.naming.impl.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:95)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:233)
at javax.naming.InitialContext.lookup(Unknown Source)
at be.java.tuto.Application.main(Application.java:17)
Thanks.
EDIT:
I just needed to invoke an EJB deployed on GF from my Tomcat server and resurrected my dependencies. And because I dont want to keep them back for myself :)...
My IDE is Eclipse so I created an User Library containing all the files shown above.
Hope this solves your problem!
I was facing the same problem. For just wanting to invoke a GF session-Bean method I had to add the complete gf-client.jar to my clients classpath.
My problem was that this library is referencing almost the whole GF-libray-folder and even after a clean-up there were >15 referenced jars left which I had to add to my clients classpath.
For me I did't want this overhead so I decided to call the remote method via JAX-WS webservice.
The advantage of using webservises is that it is very easy to add webservice capability to an already existing session-bean by annotating the bean-class with #WebService.
After publishing the bean to the appserver you're able to view your deployed endpoint and getting the WSDL. With this you can generate your webservice-stubs automatically by using the wsimport-tool shipped with your JDK and use this generated files in yor client to invoke the remote method.
See example here.
Once created those files are portable and can be used in any client.
So if your willing to change the way your client calls the remote method this would be a portable, lightweight (except of a bit more http overhead) and easy to implement alternative.
P.S.
You don't lose the ability of invoking your method via EJB-call.
Hope this helped, have Fun!

felix exthttpservice set session path for cookies

I have a webapplication that I am running in Felix osgi container. I am using jetty as the implementation for the extHttpService. Currently it is writing the cookies to the '/' root path. I would like to change this as it is causing conflicts with other web applications. Looking at jetty documentation it appears I need to set the following property.
org.mortbay.jetty.servlet.SessionPath
However, I am unable to find a way to set this using the ExtHttpService via osgi. I have tried creating a jetty.xml file, adding this to the config.properties, and setting it as a property in the call to register my servlet.
Does anyone know how to set this?
thanks,
I actually ended up patching the source for my current implementation, but on the mailing lists here, a patch has been submitted that should allow this to be configurable.

Setting Runtime Property in Web Application

I am planning to use JGroups in a web application.
JGroups by default uses IPv6 for multicasting of messages. JGroups can only be configured to use IPv4 by setting a property like the following (see docs)
-Djava.net.preferIPv4Stack=true
This does not work if set in code. What are my options when running a war file in an application server for setting this property, specifically tomcat and glassfish?
It seems to me the following route might work. First, add a ServletContextListener to your web app and register it in web.xml before JGroups is loaded.
Now, inside the contextInitialized method, use System.setProperty("java.net.preferIPv4Stack", "true").
Disclaimer: not tested.
Unless you have a specific reason to put this in code, it can easily be configured for Tomcat by setting the environment variable CATALINA_OPTS (to -Djava.net.preferIPv4Stack=true). I think the proper place to do this is to create ${CATALINA_HOME}/bin/setenv.sh and place the setting in there.

Start / stop a web application from itself?

I've made a web application using Java, Struts and running over Apache Server and Tomcat. It would be very useful to be able to restart the application from the web. I don't want to restart Tomcat, only this webapp, the same way as Tomcat Manager does it.
Do you know how can I do it? If not, any way to simulate that behaviour (reload config.properties, make Hibernate init process, etc)?
Thank you a lot.
I took a quick look at the source code for the Tomcat Manager. It looks like there's a class that's part of the Tomcat source called "Container Servlet". From the javadocs:
A ContainerServlet is a servlet
that has access to Catalina internal
functionality, and is loaded from the
Catalina class loader instead of the
web application class loader.
A ContainerServlet automatically gets passed a wrapper that can be used to get the Context and Deployer -- and the Deployer has helpful methods such as start(String contextPath) and stop(String contextPath) that will do what you want.
So, what I think you would need to do is write your own servlet that inherits from ContainerServlet, and configure Tomcat to load your servlet using the Catalina class loader (look at how the Manager is configured to see how). Note that this is probably not going to be an option for you in a hosted environment.
Then your servlet could have, say, a button you press to reload the application. I recommend putting password-protection of some kind in front of that. :)
Just hit the URLs
http://<username>:<password>#<hostname>:<port>/manager/stop?path=/<context path>
to stop and
http://<username>:<password>#<hostname>:<port>/manager/start?path=/<context path>
to start. That simulates you using the manager application.
Tomcat Manager offers an http interface to start/stop an application and other tasks. There are Ant tasks that you can use to easily access these operations.

Categories