Tomcat crashes because of native C code - Possible workarounds? - java

We have a web application hosted on tomcat and it contains calls to some of the legacy C code. Now, on in one of the scenario this C code crashed in production environment and caused the entire JVM to crash bringing the app server down for almost 15 minutes.
Question - Is there a better way to this, basically I want to load the native code in its own JVM so that the app server does not crash.

You answered your own question. Move it to another JVM and then make service calls to that JVM. If the server crashes, communications to the JVM will be lost, but your app server will still be running and can handle the failed communications gracefully.
Your options are, put the code in another app server and create a service API using JSON, Web Services etc, whatever you are more comfortable with. Or, depending on what the C code is doing, maybe just a socket level API.
Of course your C code could handle it's own sockets if you were up to writing that. But keeping it in an App server is probably best for management and monitoring reasons. And it would be quicker and more flexible in creating the API.
You would have to use your judgement as to which is the best solution for you.

We ended up by doing the following:
Moved and exposed the C specific code to a URL endpoint, i.e. RPC style web service (basically a remote call):
#WebService #SOAPBinding(style = Style.RPC)
And subsequently exposing its interface endpoint:
#WebService(endpointInterface..
During web server init published this endpoint Endpoint.publish(...) in a new java process using ProcessBuilder.
When using this, called the endpoint and got the object itself using javax.xml.ws.Service.
During server stop we destroyed the Process created in step 2.

Related

Creating a Java server which is restarted automatically on failures

I am creating a Java service which will run within a web servlet container (probably Tomcat). One portion of the server will run on its own and will not be initiated by HTTP. I know that when an HTTP call causes an exception, the web container can call it again.
I want to be sure that the part of the server which runs continuously will continue to run, even if it fails. I will handle whichever failures I can manually, but if it all fails I want something to restart it all. Are there any tools that can accomplish this easily? I am already using Spring and Tomcat, so if those can provide it, that is ideal. If not, then how about a good design pattern?
Edit: To clarify, I have a web service which will run in Tomcat. I want to run a separate thread within that service and set it up such that when the thread ends or an un-handled exception occurs, Tomcat (or something else) detects the failure and restarts the web service. I know that typically web containers have threads start from some external call and thus handle failures from those threads. What I want is something which handles a background worker thread.
Not quite clear on the design you have in mind, but it seems to me you need some sort of health check.
You can implement such a mechanism in many ways e.g. open a socket from this process that runs all time and periodically send a message.
If there is no reply then the process failed.
You could restart tomcat or implement a mechanism to restart that process.
Can not tell you more details since you do not specify much on what you are trying to do.
UPDATE:
I think that you should use JMX. It is offered by Spring and Tomcat that you already use.
Just make the process you want to monitor a managed resource and another module can check if it is alive.
If you are running inside a Servlet then as per J2EE spec, you cannot restart the container but, you can use ScheduledExecutorService to continuously monitor that your service is running and if not, then re-start it.
EDIT. More details below
You can call isTerminated() to check if the service still running and add more tasks to it, if the queue is empty.
I may be misunderstanding your problem here, but you might be over-thinking it.
There's nothing stopping you from running multiple Tomcat instances on a single machine. You could then have Server A connect to Server B to pull down information (via a web service of your choosing). This would alleviate the need for an outage on server A to cause an outage on server B (which is what I'm assuming you're trying to avoid).
This is a common way to isolate production environments simply by binding to a separate port. If Tomcat doesn't fit the bill for the service you can always run the application as a service on [insert operating system of choice] and connect to it via a proprietary protocol. Your operating system can handle restarts in that case. Typically I think the multiple Tomcat containers is the easiest approach as it is simple to install and relatively easy to set up.
Good luck, it seems like a fun system administration problem. You also might be interested in checking out Quartz job scheduling as that might fit the bill for an intermittent service.
edit: a little more detail might provide some more detailed answers.
See this post. It's a simple tomcat-watchdog shell script.

Integration of Java server application into Application Server like TomCat, GlassFish, etc

I am working on a server application that does the following:
Read data from a measuring device that is being addressed via a serial interface (javax.comm, RXTX) or sockets.
Exchange data (read and write) with another server application using sockets.
Insert data from (1) and (2) into a database using JDBC.
Offer the data from steps (1) to (3) to a JavaScript-based web app.
My current prototype is a stand-alone Java application and implements task (4) by writing the data to an XML file that is being delivered to the client via a web server (Apache), but I consider this to be a hack, not a clean solution.
This server application needs to start up and work also without any web clients being present.
I would like to integrate this server application into a Java application server, but I do not have much experience with these technologies and don't know where to start. I have tried some simple examples for TomCat and GlassFish, but that did not bring me any further because they are all built around serving web requests synchronously and stop where it would be getting interesting for me.
Is this possible to run such an app within TomCat or GlassFish?
If yes, where would be a good point to start (examples, which base classes, ...)?
Would it make any sense to split the application and implement only task (4) in a servlet, the rest in an ordinary application, communication via sockets, etc.?
Would other servers, e.g JBoss, be a better choice and if yes, why?
Edit:
The reasons I want to use a Java EE container are:
I would like to have a clean external interface for step (4).
On the long run, the application will need to scale to a huge number of simultaneous clients (at least several 10.000), so a want a standard way of scalability and application management.
In general, it's not a good idea to implement all of this in a servlet container such as Tomcat.
A servlet container is designed to service requests from a client. It sounds like you have a process which will be running all the time or at least periodically. You can do this in Tomcat, but it's probably easier to do it outside. Leave Tomcat to do what it's good at, servicing requests from browsers. It's happiest when the requests are short lived.
So I would do as you suggest, and only have step 4 in the container. You can easily interrogate the database populated in step 3, so there is no need to create web services to populate the servlet container.
For step 4, you will need to expose some services from Tomcat, either through rest, soap, whatever you like. The javascript clients can then interrogate these services. This is all completely doable with Tomcat.
For scalability, there shouldn't be a problem using Tomcat. If all it's doing is pumping data from the database to the client, there probably isn't a reason to choose a J2EE container. If you don't have need of complex transaction management or security, try using something open source. It sounds like you can get what you want from Tomcat (& hibernate & spring security if necessary). If you start to have performance problems, then the fix will probably be the same for JBoss & Tomcat: you need more servers.
My advice: stick to the simple open source solutions and move to an application server only if you find it to be necessary.
I would loosely couple the solution and not try to do everything on the Java EE/Servlet container as exchanging data using sockets (managed by the application itself) is not something you typically want to do from a Java EE/Servlet container.
Running this on a Java EE container might also be overkill as this doesn't sound like a typical enterprise application where stuff like security and transaction management is important and the app could benefit from services provided by the Java EE/Servlet container.

Java: measuring performance of an application by upgrading it to a web service

I have an application that's behaving as a server in a way. I have some consumers (another application) which send tasks to the "server" application and get something as a result. The application is implemented in Java as a console application. The problem is that I need to measure the performance of the application (CPU, memory, throughput if possible and anything else I could get). If I keep my "server" as a console application, I get a problem of application level measuring, which can be extremely hard. My idea was to "upgrade" the console application to a web service, i.e., to create some kind of a wrapper so to be able to call the "server" as a web application. I guess that the monitoring part would be much easier then.
I'd like to hear your thoughts about it. Is that a good idea? Can I get better results if I upgrade it to a web service? And how do I even do that? At this point I just want to get some results, the code can be dirty. The application is originally imagined as a web service (or something similar), the console application is just a simulation, so creating a web service instead of a console application is not a terrible thing to do.
Maybe you can use JMX protocol and JConsole to connect to your application. With JConsole you will have detailed information about memory usage, CPU usage, threads etc. It will also allow you to control your application on the fly by means of MBean.
Take a look at: http://download.oracle.com/javase/1.5.0/docs/guide/management/jconsole.html
Yes its a good idea to make your application a Web Service. It will make your application secure and scalable out of the box.
You can chose yourself that which web service you want to apply. I would suggest you to go for RestFul web service (JAX-RS). And you can use sl4j for logging all the information about the mem and cpu usage.

Exposing C++ program as a Web Service

How to expose a C++ program as a Web Service?
Or is it a better idea to invoke C++ from Java and expose the resultant Java as a Web Service.
In any case, the C++ program should not undergo any changes.
Consume C++ program in Java WebService end point and expose java webservice
Use JNI to consume C++ program
Nice article from JavaWorld
Interestingly, webservices work on http protocol, which means that you can't "host" a webservice written in C++ without having an http server. Since each web server will have it's own mechanism of writing "hooks" or extensions, the next obvious question is which web server would you like to chose.
Let's say you want IIS on Windows. It's possible to use ISAPI extensions; so you need to know how to write one, which complies with web services standards. Or, alternatively, it's better to learn how to do it in C++ with Visual Studio, which will have lots of built-in stuff to help you get started.
In short, there is no "standard" way of exposing a web service in C++ and you have to be "platform" specific. Windows with IIS has one way of doing it. Apache Axis C++ has another.
You can try c-sevice-interface https://github.com/Taymindis/c-service-interface.
It create a C/C++ program as a service port and listening to NGINX fcgi.
This is a small bridge engine which can handle high load of request, any segfault will not break the engine, it will catch and free the thread, it is built on top NGINX, FCGI. You can setup the proxy, load balance, authentication via NGINX before reach to your interface.
The link shown as below is a wiki to Guide you how to startup from scratch.
https://github.com/Taymindis/backcurl/wiki/How-to-build-BackCurl-for-cpp-Android-development

When is a Web Service constructor called? [Java Netbeans 6.7.1 & Tomcat 6.0.18]

I am migrating a Java RMI application to Java Web Service (school assignment) and I've encountered an issue...
Currently my Java Server creates an instance of the Remote Object, this object has a constructor and takes a parameter (int ID) which tells it which database to load in memory - works like a charm ...
Now, migrating this to Web Services is causing my a problem - first I needed to add a default constructor because it wouldn't deploy without it, and then while doing some reading all these discussions about "stateless web services" kept coming up ...
For example, if I "start" my webservice with parameter(0) it would load from Databse 0 and all requests from Clients would be done using that data... I want this to only happen when I start the WebService and NOT everytime the client connects... Loading from the DB is expensive and takes time, so I want to do it once so that clients when they connect just deal with the data in memory ...
This is how it works with my Java RMI .... but can this also work with Web Services?
Any advice would be much appreciated.
Thanks,
Perhaps you should consider splitting your presentation from the backing service. Consider the WebService simply a presentation layer and the database processing the service being presented. The web service should really just be referencing the database via a handle to a single instance rather than actually being that instance. This means that the "state" is then held in the database instance not the web service.
One way to consider this (although I would not suggest that you implement it this way) is to consider the Web Service as the RMI client of the database rather than the RMI server service.
Hope this helps.
Kind regards,
Malcolm

Categories