JMX Html Adaptor - java

I'm looking for a simple and straightforward way to add JMX capacities to application, preferably exposed via http. Below is simple code snippet, which, I suspect, should run http server on 8000. And I should be able to access it via http://localhost:8000. However page can't be opened. I can't find proper documentation how it is supposed to work.
jmxtools-1.2.jar is included to classpath. Java version - 1.6
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import com.sun.jdmk.comm.HtmlAdaptorServer;
public class JmxHttpAdapter {
public static void main(String[] args) {
try {
com.sun.jdmk.comm.HtmlAdaptorServer adapter = new HtmlAdaptorServer(8000);
MBeanServerFactory.createMBeanServer().registerMBean(adapter, new ObjectName("Adaptor:name=html,port=8000"));
adapter.start();
Thread.sleep(100000);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

Not sure why that adaptor is not working, but you can find documentation in Chapter 2 of the Java Dynamic Management Kit 5.1 Tools Reference Guide.
MX4J also has an HTTP Adaptor which is also kind of old, but you may find it better documented.
You should take a look at Jolokia. It is more contemporary and still under active development. It is an HTTP based REST agent with several options for installation including a WAR and a Java Agent. That does not get you a UI though, although there's plenty of tools you can use with it. The same developer is working on a UI project for Jolokia called Aji but I am not sure what state is in right now.
Here's a few references to UIs built for Aji:
Jolokia + Highcharts = JMX for human beings
JMX over HTTP with Jolokia and javascript

Related

Website in OSGi that consumes REST web service running in background

I spent quite a few days now trying to figure out how to add a website in OSGi.
I hava Restlet web service running with Jetty extension to use Jetty as a connector. This feature provides different resources under multiple URLs.
But I would also like to have a small website running on the system that can be accessed by the user. I wanted to use some HTML,Javascript,CSS and provide the current data status with some graphs and pictures.
I assume since Jetty is running in the background I would be able to deploy this website on Jetty and maybe call the server resources provided by Restlet in Javascript.
Apparently nothing worked except the restlet services.
My question would be is it possible to add a WAB bundle and expect it to work(Since Jetty is running in background)? Or is there any better way to add a website in OSGi?
Or
The only option I have now is, since it is possible to return an HTML form as a representation, add all my javascript code inside the HTML form and send it as a response to GET request(Which I believe is a mess).
Everything will run in Raspberry pi so I can only have a very small footprint. I am using Equinox, Restlet 2.3.0 and Jetty 9.2.6.
I would really appreciate if someone knows a link where i could get info on getting at least a sample page running in OSGi. I have tried many with no luck.
I recommend you to have a look at how it is done in Apache Karaf (https://github.com/apache/karaf). More on Apache Karaf and WebContainers here: http://karaf.apache.org/manual/latest/users-guide/webcontainer.html
In fact, Jetty is internally used by Restlet under the hood through its connector feature. This way, it's not convenient (and not the correct approach) to register dynamically applications.
That said, Restlet is really flexible and dynamic. This means that you can dynamically handle bundles that contain Restlet applications in a similar way than WAB bundles, i.e. attach them to virtual hosts of a component.
Here is the way to implement this:
Create a bundle that makes available the Restlet component into the OSGi container. You should leverage the FrameworkListener listener to be able that all connectors, converters, and so on... are registered into the Restlet engine:
private Component component;
public void start(BundleContext bundleContext) throws Exception {
bundleContext.addFrameworkListener(new FrameworkListener() {
component = new Component();
(...)
component.start();
});
}
public void stop(BundleContext bundleContext) throws Exception {
component.stop();
}
When the component is started, you can look for bundles that are present in the container and contained Restlet applications. For each bundle of this kind, you can register a dedicated OSGi service that make available the internal Restlet application you want to register against the component.
ServiceReference[] restletAppRefs = bundleContext.getServiceReferences(
"restletApplication",
null);
if (restletAppsRefs != null) {
for (ServiceReference restletAppRef : restletAppsRefs) {
RestletApplicationService descriptor
= (RestletApplicationService) bundleContext
.getService(serviceReference);
String path = descriptor.getPath();
Application restletApplication = descriptor.getApplication();
// Register the application against the component
(...)
}
}
Registering applications against the component is
try {
VirtualHost virtualHost = getExistingVirtualHost(
component, hostDomain, hostPort);
if (virtualHost == null) {
virtualHost = new VirtualHost();
virtualHost.setHostDomain(hostDomain);
virtualHost.setHostPort(hostPort);
component.getHosts().add(virtualHost);
}
Context context = component.getContext().createChildContext();
virtualHost.setContext(context);
virtualHost.attachDefault(application);
component.updateHosts();
application.start();
} catch(Exception ex) {
(...)
}
You also need to take into account the dynamics of OSGi. I mean bundles can come and go after the start of the OSGi container itself. You can leverage
bundleContext.addServiceListener(new ServiceListener() {
public void serviceChanged(ServiceEvent event) {
if (isServiceClass(event, RestletApplicationService)) {
int type = event.getType();
if (type == ServiceEvent.REGISTERED) {
// Register the Restlet application against the component
} else if (type == ServiceEvent.UNREGISTERING) {
// Unregister the Restlet application
}
}
}
});
Hope it helps you,
Thierry
There are many options available to you - OSGi doesn't really impose many restrictions on what you can do. If you want to use OSGi's capabilities then here's a couple of ideas:
One option would be to deploy a WAB. You'll need to ensure that your framework has the necessary OSGi Services running though. Just because some bundle is using Jetty internally it doesn't follow that the necessary OSGi services are running.
The bundle org.apache.felix.http.jetty does provide the necessary services to deploy a WAB. Version 2.2.2 is 1.3MB on disk, and embeds its own copy of Jetty. Other implementations are available (e.g. Pax-Web, as used in Karaf - which also embeds Jetty)
Another option would be to use the OSGi Http service directly (again you'd need to include a bundle which implements this service (like the Felix one mentioned). A call to org.osgi.service.http.HttpService.registerResources() will serve up static content from within your bundle.
If the this additional footprint is a real concern then you might want to look at how you can get Restlet to use the OSGi http service, rather than providing it's own via embedded Jetty.
Yet another option would be to take a Jetty centric view of things. Restlet's embedded Jetty is probably not configured to serve arbitrary content from disk. You could look at either re-configuring the embedded Jetty to do this, or consider deploying Restlet to a 'standard' Jetty install. Personally, I'd try the latter.

Invoke a GWT RPC Service from Java, problems with RPC policy

I need to invoke a GWT RPC service from simple Java code. Yes, I read this
Invoke a GWT RPC service from Java directly
However, my issue is that I do not have access to the web application code (though I could ask and obtain some parts of it), so I cannot just add it to the build path of my Java project. All the info I read from the internet is not clear on what exactly needs to be imported.
The question is: what is the minumum that I should include in my project in order to make the call to the service work (using syncproxy gwt for example)? Will it be enough to redefine the client interfaces inside my code or should I do some compiling work as well?
EDIT: I've done some testing locally with the default web app running on localhost. I created a new java project, imported the sync and async service interfaces and the RPC serialization policy I found in the WAR folder of the web app. This is my testing code
import com.gdevelop.gwt.syncrpc.SyncProxy;
public class serviceCall {
private static final String MODULE_BASE_URL = "http://127.0.0.1:8888/gwttestapp/";
private static final String SERVICE_NAME = "greet";
public static void main(String[] args) {
GreetingService rpcService = (GreetingService) SyncProxy.newProxyInstance(GreetingService.class, MODULE_BASE_URL, SERVICE_NAME, "CB32CC2E454EE7E1088B2E29CEB44F84");
String result = rpcService.greetServer("SyncProxy");
}
}
However the server seems not to recognize the RPC policy, since I get the following exception:
Exception in thread "main" com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: This application is out of date, please click the refresh button on your browser. ( Blocked attempt to access interface 'GreetingService', which is not implemented by 'com.apptesting.server.GreetingServiceImpl'; this is either misconfiguration or a hack attempt )
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at com.gdevelop.gwt.syncrpc.SyncClientSerializationStreamReader.instantiate(SyncClientSerializationStreamReader.java:746)
at com.gdevelop.gwt.syncrpc.SyncClientSerializationStreamReader.deserialize(SyncClientSerializationStreamReader.java:816)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.readObject(AbstractSerializationStreamReader.java:119)
at com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:204)
at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.java:193)
at com.sun.proxy.$Proxy0.greetServer(Unknown Source)
at serviceCall.main(serviceCall.java:11)
Anybody can help?
Try initiating the rpcService without the .gwt.rpc policy specified. IE, just make the call:
GreetingService rpcService = (GreetingService) SyncProxy.newProxyInstance(GreetingService.class, MODULE_BASE_URL, SERVICE_NAME);
You generally do not need to specify the exact serialization policy as the RPC system should automatically figure it out. In fact, it's better not to specify it because the deployed site will change the serialization policy file as the back-end changes. Take a look at the source and testing wiki (https://code.google.com/p/gwt-syncproxy/wiki/SourceAndTesting) for some guidance on on setup need needs. The source code for the Android testing app may provide you some code guidance on creating a functional standalone (if you ignore the AsyncCallback implementations)
In general answer to your question, for deployment purposes, all you really are the interfaces you specified (*Service & *ServiceAsync). For testing purposes in your development environment, you can mock some *Impl files that will provide you some generic responses for testing (such as in the default web-app). Take a look at the Android Wiki in the sync-proxy project (https://code.google.com/p/gwt-syncproxy/wiki/Android) at the setup section for a quick overview on linking the needed files.
Disclaimer: I'm a developer for the Android syncproxy library

Requests to servlet wait in queue

I am developing web app build in GWT using GWT RCP. Application is designed for instant messaging which I use redis messaging for.
When waiting in servlete on a message and I am subscribe on that channel in redise everything works as planned. Though when number of awaiting requests on server is more than 5, the 6th request doesn't start to be processed and waits in que until one of the previous requests is processed. I wasn't sure if the problem is in redis (I am using jedis library) therefore I tried to call directly sleep on currentThread but it behaved the same.
public class TestServiceImpl extends RemoteServiceServlet implements
TestService {
#Override
public void syncWait(Date time) {
try{
Thread.currentThread().sleep(10000l);
}catch (Exception e) {
getLogger().error("sleep error", e);
}
return ;
}
}
It's not just about one particular servlet, when 5 requests are opened, 6th doesn't even load static content. I tried it on jety, glassfish and tomcat.
I also tried to change settings of threadpool in glassfish, maxthread-count I set up on 200 but it didn't work.
Could you please advice on how to increase the number of requests processed pers session and per server?
For this you REALLY want to use one of the servlet Comet implementations and an NIO connector. I'm not intimately familiar with Glassfish or Jetty, but on Tomcat you can use a combination of APR (see http://tomcat.apache.org/tomcat-6.0-doc/apr.html) and advanced IO (see http://tomcat.apache.org/tomcat-6.0-doc/aio.html) to do what you want.
Please note that using Tomcat's Advanced IO is more complicated (and less well documented) than the standard Servlet 2.5 api.
Resin, Tomcat 7 and Glassfish (I believe) support the Servlet 3.0 spec which also offers support for similar features: you may want to take a look at that.

In-process SOAP service server for Java

OK, I am developing a program which will be deployed to lots of machines (Windows, Linux, AIX, z/Linux, openVMS, etc.). I want that application to contain a SOAP web service, but I don't want to bundle tomcat or run a separate service for the services (I want them in the same process as the rest of the application).
Basically what I'm looking for is something where I can define a class (say WebServices). I'm OK with writing WSDL or any other kind of service description as well. The I want something like this:
SOAPServer server = makeMeASoapServer();
//do config on the server
server.add(new WebService(...));
server.listen(port);
Obviously the names and parameters will be different.
I've been looking at Axis, and it seems like it provides this, but I don't know what classes I need to use. Am I crazy in wanting this kind of behavior? I can't believe more people aren't looking for this, I do this all the time with embedded web services within .NET clients.
Seems jdk 6.0 already comes with a jax-ws implementation, and a little server you can embed.
I havn't figured out all the pieces but here's a start:
mkdir -p helloservice/endpoint/
helloservice/endpoint/Hello.java :
package helloservice.endpoint;
import javax.jws.WebService;
#WebService()
public class Hello {
private String message = new String("Hello, ");
public void Hello() {}
public String sayHello(String name) {
return message + name + ".";
}
}
helloservice/endpoint/Server.java:
package helloservice.endpoint;
import javax.xml.ws.Endpoint;
public class Server {
protected Server() throws Exception {
System.out.println("Starting Server");
Object implementor = new Hello();
String address = "http://localhost:9000/SoapContext/SoapPort";
Endpoint.publish(address, implementor);
}
public static void main(String args[]) throws Exception {
new Server();
System.out.println("Server ready...");
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting");
System.exit(0);
}
}
Build the thing:
mkdir build
javac -d build helloservice/endpoint/*java
$JAVA_HOME/wsgen -d build -s build -classpath . helloservice.endpoint.Hello
Run the thing:
java -cp build helloservice.endpoint.Server
Somethings running on http://localhost:9000/SoapContext/SoapPort now.
You can get the wsdl on http://localhost:9000/SoapContext/SoapPort?WSDL
Havn't gotten around to making a client yet..
In addition to nos's great answer, I found a class in Apache axis called SimpleHTTPServer which I'm pretty sure does the same thing but only requires Java 1.5 for those of you stuck with 1.5
I'm not going to explore it since I'm going to use the other solution, so I haven't actually verified it does what I think it does, but I'm pretty sure it does.
Most(/all?) Java SOAP server implementations provide a Servlet (the javax.xml.ws.Endpoint approach in another answer does look a bit simpler though...). Some SOAP implementations you could consider are: Apache CXF: cxf.apache.org, Apache Axis2: ws.apache.org/axis2/ or Spring Web Servies: static.springsource.org/spring-ws/site/ .
The most popular embedded Java web server seems to be Jetty, you can configure it either programatically (using plain Java or Spring beans) or using a custom XML format.
To address the main question directly, another approach would be to go with Jetty's embedded server. See this link for details. The links from the aforelinked page help you understand both the simple web server (i.e., one that serves up static pages; though I am fully aware "simple" is a horribly vague term wrt web servers) and the web server that helps you deploy web services.

Servlets + JAX-WS

I'm trying to expose a web service method via JAX-WS annotations. Many examples I've seen reference the EndPoint.publish() method to quickly stand up the service in a standalone app (ex from Java Web Services: Up and Running, 1st Edition):
public class TimeServerPublisher {
public static void main(String[ ] args) {
// 1st argument is the publication URL
// 2nd argument is an SIB instance
Endpoint.publish("http://127.0.0.1:9876/ts", new TimeServerImpl());
}
}
One thing that I'm missing is how to accomplish essentially the same thing but in an existing app. Would I make a servlet to handle this? What is the proper way to publish this service in an existing WAR file?
In a container you don't have to publish like this. The container will do the publish. If you plan to use it in JBoss server try JBossWS otherwise for Tomcat or any other server Axis2 may be the better choice.
Read more from the following links.
http://jbossws.jboss.org/mediawiki/index.php?title=JBossWS
http://ws.apache.org/axis2/
This depends on what WS stack you are using.
If you are using Java 6 then that includes the JAX-WS reference implementation, then you can consult the documentation about JAX-WS RI WAR contents.
As #Jerrish and #andri coments, there are different aproaches and solutions, depending on your concerns.
The idea behind is that you don't need to set the configuration (port, etc) when will be published your web service. The best approach could be to set this via configuration files (XML, properties, etc) or using #Annotations.
For example, if you're accustomed to use frameworks like Guice or Spring, you know that is possible/recommended to start the context of your application publishing or initializing some objects, factories, datasources, etc and publishing webservices is another task that can be done in this time, because will be available when you will start your application, isn't?.
By the way, I've good experiences with CXF and another solution could be Spring Web Services another powerful solution for creating web services.

Categories

Resources