Running Java on a Web Server - java

I have written a standalone Java application that I've packaged into a jar file that takes in some command line arguments, does some hardcore computations, and then writes out the result to a file along with some output to the default output stream pointing to where the file with the results are.
I now want to create a website around this technology. The idea is that the user can fill in an html form, post it to a webpage, which would then call the Java application, parse the results from the Java app, and display it to the user.
Currently, I am using a little bit of PHP to collect the data from the post request, and then just using an exec call: java -jar -Xmx128m myapplication.jar command-line-arguments
Is this bad?
I do have several thousand visits to my website each day and each execution of the Java application can take upwards of 30 seconds to a minute, so I don't want to be overly inefficient. It seems like there would be a better solution than having to call Java directly for every request.
I keep hearing things like java servlets, beans, tomcat, glassfish, etc., but I don't understand what they are and how they would benefit me. What do these get me? Faster results because the Java JVM doesn't have to be created each time I run the application? Less memory usage? I obviously want it to run as fast as possible with as little memory footprint as possible.
So, what is the best approach that I can take here? I don't want to do any serious rewriting of my application as there is a lot of code (so rewriting it to C or C++ is out of the question).
Thanks.

Ok, servlets are smalish applications that are designed to run inside of a container. They provide an extension point for you to insert your java code into either a simple servlet container like tomcat, or a more fully featured application server like glassfish. You want to do this because the application server does the heavy lifting of dealing with the http interaction and provides other features like security, logging, session management, error handling, and more (see the servlet specification).
When you make your application live within an application conatiner (web server with all those other extra features), you can also manage the lifecycle of your application better. You'll be able to start and stop the application without shutting down the web server, redeploy, start more instances, etc. Plus, when you come up with that great second application, its easy to drop it in right next to the first one. Or, you can cluster several machines together for easy redundancy and load balancing, features of the application server.
This is just a start, there are many more features, technologies, and frameworks out there to help you make container based applications. Servlet tutorial.

[Do these get me] "Faster results because the Java JVM doesn't have to be created each time I run the application?"
Yes.
And -- bonus -- you can replace PHP so your entire site is in a single language: Java.
Further, you can consider revising your use cases so it isn't a painful 30-60 seconds in one shot, but perhaps a series of quicker steps executed interactively with the user.

Run your code inside a servlet container.
Assuming that you need to keep your website in PHP and as you already have java installed on your machine, simply install a free servlet container (such as Apache Tomcat, or Jetty). Configure to run the servlet container on an unused port. (8080) is their default.
These servlet containers are really java based webservers, just like Apache, however specialized in serving java code.
The most obvious advantage of using a java webserver rather than a new java.exe invocation for each request, is that your java virtual machine (jvm) will always be "hot", up and running. Each new start of the java.exe (jvm) will give you those extra seconds of waste.
The second advantage of using a servlet container, is that the container will enable your code to run in a new thread, inside the jvm, for each new request. You will have no problem providing your service to your thousands of users a day. Most likely, your machine will crash if you were to start hundreds of java instances rather than one.
Place your code inside a servlet. It really is easy even for a newcomer. You will talk to the servlet via HTTP (doGet or doPost methods of the servlet). Pass the php request form to this servlet and have the servlet give you back whatever: a page, a json object, xml or plain text.

You probably don't want to invoke the java app directly from the website. Like you said, if the java process takes 30 seconds to run, your web server is going to get way bogged down, especially if your site is getting pounded.
You may want to look into web-services (and possibly a message queue) for dispatching back-end processing requests. The PHP page could call the web-service on the server, which could then put a processing request on a queue, or just kick off the java app in an asynchronous fashion. You don't want the HTTP request to wait for the java app to finish, because, while it's processing, the user will just have a hung browser, and the HTTP request might timeout.
Once the java app finishes, it could update a database table, which the user could then access from the website.

The easiest thing to start with would be to embed a webserver in you application. Have a look at Jetty.

Related

Ruby on rails with jRuby

I'm working on a Ruby on Rails app, currently hosted on Heroku.
We have about 5 web dynos and about 2 worker process running on average. But because we're using adeptscale these can change a lot, and the cost is increasing from month to month.
We're thinking about changing the process and the infrastructure (using our own, off of amazon/google etc). And also because of the performance, access to java libraries and other gains we're planning to go with jRuby.
I haven't got much experience with jRuby at all, but I do have Java experience. So I have a few questions:
Question intro: Since rails philosophy/approach differs from Javas, i.e ruby webserver uses far less memory but can only process one request at a time, and so having multiple servers sort of compensates the inability to process multiple requests.
If we go with jRuby (and have our rails project packaged as a war file and deployed to any servlet container i.e Tomcat or Jboss(more than just container)), will we be able to process multiple requests then?
Question intro: Currently we got some application logic running in the workers(instead of blocking the webserver, and not being able to serve other clients/browser clients). i.e when users submit some form and then our app needs to contact the 3rd party service to return the response, we simply let the worker do the workload of getting back from the 3rd party service and updating the ui (which reports waiting status) via websockets that the 3rd party service returned x/y or whatever status.
If we switch to jRuby, how will we achieve the similar logic? I mean do we go with the java code which has some kind of thread pool of workers and then free workers do the workload of contacting the 3rd party service etc? How would we go about this if we decide to go with jRuby?
1) You can serve multiple requests at a time in jruby with nearly any container, but you can also serve multiple requests at a time with mri-ruby. You only have to have a threadsafe app (config.threadsafe! is default in rails4). Different rack servers have different approaches to serve multiple requests at a time. For example unicorn uses multiple processes while passenger or puma go for a multi-threaded approach.
In my experience jruby containers like jboss or tomcat are more complicated to configure properly. But there are things like tourquebox, trinidad that help you with this. But you can even still go for some of the ruby servers (e.g. puma) that dont use c extensions.
2) If I understand you correctly you are looking for some background-processing library? You can use sidekiq or resque with ruby or jruby (while jruby will be faster in general, and its easier to debug memory leaks). You can even use ruby for your rack servers and jruby for your workers (can even be run in parallel with things like rvm/rbenv)
In general I would only go for the jruby option if you know what you are doing and need better performance for your app servers or if you want to speed up your worker servers. If I was you I would probably stay in the ruby world and use puma for your app and sidekiq as a background service. Both are very elegant and need not so much configuration.
Yes, JRuby uses Java threads and is really multithreaded. And I can say that it's really good in integration with Java, even using classes for JNI.
I can recommend next servers (some have already been mentioned):
puma (https://github.com/puma/puma)
any servlet container (even IBM WebSphere Application Server!) - just use warbler (https://github.com/jruby/warbler)
The 'simplest' way to run application on servlet container is make .war with warbler. Usually resulting .war file includes all dependencies and JRuby interpreter, so resulting file usually is 30 Mb. But I think that it is not so easy to setup warbler, then I wouldn't recommend this way if you don't really need to run Rails in enterprise Java environment.
And I would just remind that Rails opens DB connection for any request, then default size of DB connection pool of 5 isn't enough - don't forget to increase it before load testing :) (e.g. default thread pool for puma is 16, IBM WAS is 50, Tomcat - 200 threads).
I agree with smallbutton.com that puma is good choice. Finally, with puma you can switch between JRuby and other interpreter almost easy (in my experience there is one difference - gem's names)

How to build a distributed java application?

First of all, I have a conceptual question, Does the word "distributed" only mean that the application is run on multiple machines? or there are other ways where an application can be considered distributed (for example if there are many independent modules interacting togehter but on the same machine, is this distributed?).
Second, I want to build a system which executes four types of tasks, there will be multiple customers and each one will have many tasks of each type to be run periodically. For example: customer1 will have task_type1 today , task_type2 after two days and so on, there might be customer2 who has task_type1 to be executed at the same time like customer1's task_type1. i.e. there is a need for concurrency. Configuration for executing the tasks will be stored in DB and the outcomes of these tasks are going to be stored in DB as well. the customers will use the system from a web browser (html pages) to interact with system (basically, configure tasks and see the outcomes).
I thought about using a rest webservice (using JAX-RS) where the html pages would communicate with and on the backend use threads for concurrent execution.
Questions:
This sounds simple, But am I going in the right direction? or i should be using other technologies or concepts like Java Beans for example?
2.If my approach is fine, do i need to use a scripting language like JSP or i can submit html forms directly to the rest urls and get the result (using JSON for example)?
If I want to make the application distributed, is it possible with my idea? If not what would i need to use?
Sorry for having many questions , but I am really confused about this.
I just want to add one point to the already posted answers. Please take my remarks with a grain of salt, since all the web applications I have ever built have run on one server only (aside from applications deployed to Heroku, which may "distribute" your application for you).
If you feel that you may need to distribute your application for scalability, the first thing you should think about is not web services and multithreading and message queues and Enterprise JavaBeans and...
The first thing to think about is your application domain itself and what the application will be doing. Where will the CPU-intensive parts be? What dependencies are there between those parts? Do the parts of the system naturally break down into parallel processes? If not, can you redesign the system to make it so? IMPORTANT: what data needs to be shared between threads/processes (whether they are running on the same or different machines)?
The ideal situation is where each parallel thread/process/server can get its own chunk of data and work on it without any need for sharing. Even better is if certain parts of the system can be made stateless -- stateless code is infinitely parallelizable (easily and naturally). The more frequent and fine-grained data sharing between parallel processes is, the less scalable the application will be. In extreme cases, you may not even get any performance increase from distributing the application. (You can see this with multithreaded code -- if your threads constantly contend for the same lock(s), your program may even be slower with multiple threads+CPUs than with one thread+CPU.)
The conceptual breakdown of the work to be done is more important than what tools or techniques you actually use to distribute the application. If your conceptual breakdown is good, it will be much easier to distribute the application later if you start with just one server.
The term "distributed application" means that parts of the application system will execute on different computational nodes (which may be different CPU/cores on different machines or among multiple CPU/cores on the same machine).
There are many different technological solutions to the question of how the system could be constructed. Since you were asking about Java technologies, you could, for example, build the web application using Google's Web Toolkit, which will give you a rich browser based client user experience. For the server deployed parts of your system, you could start out using simple servlets running in a servlet container such as Tomcat. Your servlets will be called from the browser using HTTP based remote procedure calls.
Later if you run into scalability problems you can start to migrate parts of the business logic to EJB3 components that themselves can ultimately deployed on many computational nodes within the context of an application server, like Glassfish, for example. I don think you don't need to tackle this problem until you run it to it. It is hard to say whether you will without know more about the nature of the tasks the customer will be performing.
To answer your first question - you could get the form to submit directly to the rest urls. Obviously it depends exactly on your requirements.
As #AlexD mentioned in the comments above, you don't always need to distribute an application, however if you wish to do so, you should probably consider looking at JMS, which is a messaging API, which can allow you to run almost any number of worker application machines, readying messages from the message queue and processing them.
If you wanted to produce a dynamically distributed application, to run on say, multiple low-resourced VMs (such as Amazon EC2 Micro instances) or physical hardware, that can be added and removed at will to cope with demand, then you might wish to consider integrating it with Project Shoal, which is a Java framework that allows for clustering of application nodes, and having them appear/disappear at any time. Project Shoal uses JXTA and JGroups as the underlying communication protocol.
Another route could be to distribute your application using EJBs running on an application server.

Architecture of Website based on java

I've just started programming with Java, so might appear as silly question, but I was not able to find simple answer on the internet. This is "big" question which I have to answer before getting too deep into development, so you can help me to save a lot of time on trying different approaches.
I am currently creating a website using Java. Important feature of this website would be realized through separate Java thread (like daemon) which must be run in background for as long as the user is on the website. At the sametime, website applets must have means of communication with this thread.
I see three potential solutions to this:
Create traditional multipage website with stand-alone java applets in each separate page. I am not sure if it is possible, the following questions arise:
is it possible for java thread created by java applet to continue execution after user navigated to another webpage (on the same website)? I assume that yes.
is it possible for newly launched java applet to communicate with java thread already running in background? (I've seen part of documentation covering communication between java applets through JavaScript, not sure that this can be used in my case. Any other options?)
Create single-page website, with one single java applet, responsible for all navigation and rendering all pages. This solves the problem with background daemon, which becomes easy to implement and communicate with, as part of single applet, but raises one more questions:
I know that applet can modify current webpage. Is it feasible to use this feature to simulate navigation between different pages?
Create Java Webstart application, basically by taking the single java applet from p.2 and converting it into stand alone application.
I want the whole thing to have a look and feel of website, so I would prefer option 3 over option 2 and option 1 over option 2.
Thank you for any thoughts you share.
UPDATE:
Does anybody know answers specifically to the two questions under p1? If it is possible to work with java threads the way described?
Now I would most probably opt for making a Java Webstart Application. This should be the least painful way.
UPDATE 2:
I finally decided to work on single java applet, which can be easily converted to JWS application if needed. Nature of my project is that I need to make impression of working with website, that's why I am putting additional efforts to make it appear as a website. For knowledgeable people it will be obvious, that it is more like a local application.
Solution I chose has following benefits in my situation:
- easily convertable from JWS application to Java applet and back.
- no problems with running background thread and communicating with it.
- more reliable security (meaning that I don't need to use any mechanisms to pass over session ids from one applet to the other)
Contras:
- if size gets large, start up will be slow - I hope to avoid this.
- Security issues - I tried signing the applet and it helped a lot.
- Work of navigation buttons in browser (back and forth) - I hope to be able to replicated it in applet. Think applet should be able to catch this event.
Java thread [...] which must be run in background for as long as the user is on the website
If the thread being forked is to preserve state while the client is logged in then I would use a database, memory cache, or some other persistance layer to hold the client session state. This is a much more typical model. You can also have multiple frontends that share session information across the network.
If you are not talking to a browser then creating a stand-alone web application may be the best choice. You can still use HTTP as your transfer protocol in which case I'd recommend using a Java web implementation like Jetty. This would involve significantly less technology and complexity.
If you need to implement web pages, I would certainly use proper frontend models and technology. You should separate your pages into multiple applets -- or multiple controllers/views in the MVC model. Using the applets should be fine. They (or the controllers) should call a centralized service which starts, communicates with, and stops the background threads depending on the information flow.
I would also certainly have another background thread running to time out your client threads in case a client never returns. Your worker threads could just exit after a certain amount of waiting.
Hope this helps.
is it possible for java thread created by java applet to continue execution after user navigated to another webpage (on the same website)? I assume that yes.
Yes. Threads that are forked will continue to run until they terminate or (if daemon) the process terminates.
is it possible for newly launched java applet to communicate with java thread already running in background?
Sure. What they need is some mechanism to be able to share data. For example, your background thread service could keep a Map of the thread objects with the key being some sort of client-id. Whenever a thread wanted to talk to it's background thread then it could call the service to lookup the thread by id. Something like:
BackgroundStream thread = threadService.getThread(clientId);
thread.callMethod(...);
If there was some sort of synchronous question/response then you'd need to have a condition variable or something. Read up on Java threads for more information.
There's an architecture used in Website applications in Java, it's called a Model-View-Controller. Frameworks such as Java Server Faces (Standard on Java EE 5 and higher), Struts (1.x or 2.x), Spring, Apache Wicket, etc. were designed to create web applications using MVC model. The question is, would you prefer the component-based architecture of the framework (such as JSF) or not (which you shouldn't be worried about at this moment)
Applets is defnitely a bad choice as applets are downloaded to client side. Some browsers don't support Applets especially in mobile web browsers and its difficult to apply security settings to untrusted applets, plus you may not know if the client has blocked the applet or not.
Applets are a bad choice because of 2 reasons:
1) First, they are executed on client's browser and not on server. Therefore you cannot perform any backend processing(Business logic or fetching data from server database) using applets.
2) Applets are very buggy and have security issues. That's why applets are out of fashion these days.
Now coming to how you can create website using java technology, for that you need to start understand Java Server Side programming. Start learning about Java Servlets and Java Server Pages. To put it in simple terms, they are java programs which are executed on a web-server or application server.
then start reading about Java Enterprise Edition.
refer this tutorial for Java Enterprise Edition

Spring / Java, good method for remotely interacting with command line Java app on another server?

I am working on a Spring web application where I have a need to interact with a remotely based command-line java application to run a simple search query on this application and get back the results. I initially had integrated this into my Spring app but my app is, itself, needing a lot of memory (its an app that involves huge amounts of data) and I don't think they can coexist on one server anymore.
I am running everything on Amazon ec2 so the latency between the servers should be really low. I figure I could use a direct SSH connection but am not so sure if this is the best approach. I'd like to keep the command-line app I am interacting with as simple as possible (would rather not make it into a web-service if I don't have to). I'm still fairly new to Java so sorry if this sounds like a basic question.
You have several options other than a web service. Some of them are:
Protocol Buffers
JMS
Simple socket based client/server Java
Thrift
Assuming you have or can have spring on both ends -
Exposing service objects and consuming them from a different process becomes extremely trivial using Spring's remoting support. (RmiServiceExporter may be most appropriate and least trivial to setup in this case)
It really does away with all the boiler plate code and let's you focus on your business/service logic.
You can write a hello world service and consume it from another Java program in less than twenty minutes. Once you have this "infrastructure" setup, you are free to focus on your actual business logic.
(You absolutely don't have to know rmi to get this working though rmi working knowledge may help if you run into problems. But then, what is SO community for? ;))

Java applet communication with Rails application

I'm creating a Rails application and on it, there should be a Java Applet.
My question and problem is that the applet must be tightly integrated with the Rails parts. I must be able to get a list of all users, update an image, etc... And there's a surprisingly small amount of information available on the Internet of how to use applets with Rails. So please give me some hints. What is the best way to do it?
Send parameters to the applet?
Use Rails REST interface from the applet?
Use JRuby somehow?
Other....?
Thanks!
Can you provide more details? In the meantime, here's my take on your questions:
Send parameters to the applet?
Your rails app will be able to serve the applet, but once served I don think you'll be able to send messages to it (however you will be able to respond to messages from it, which is perhaps what your asking).
Use Rails REST interface from the applet?
You've kind of answered that one yourself. REST is an interface design and therefore can be accessed from anything that can issue a HTTP request. The trick is to correctly construct the URL so rails knows what you want to do. There's good info on configuring rails routes (REST and non-REST) here http://guides.rubyonrails.org/routing.html
Use JRuby somehow?
You could use jruby for this, but you dont need to. Your server (rails) and your client (browser/applet) talk to eachother via http and so don't need to be the same language or run on the same VM.
Hope that help....
I think the reason you probably haven't found anything specific about Applets and Rails is that they function a bit at different levels and aren't really dependent on one another. It looks like Rob was trying to clarify a few things, so I'll take it another step just to be sure we are all on the same page.
The job of Rails is to generate and serve up HTML/XML/Javascript/images via a web server to the user's web browser for rendering. Part of that HTML will be an APPLET (or possibly OBJECT) tag, which instructs the browser to load the applet. Usually, this instructs the browser to invoke the Java Plug-in and lets it handle loading the applet. Once loaded and running, however, even though the applet is displayed on the current web page in the browser (or maybe in another window even), it really isn't terribly aware of the web page it is sitting in. For the most part, applets don't care about the browser or the page they are "part of". So if an applet needs more information, or needs to ask for data, it usually will just send an HTTP request to the server it came from. It would then parse the data and update itself.
I am assuming what you probably need is for something to be clicked or entered into the applet, and that data be used to update the web page that Rails is serving to the browser. With an applet, you pretty much have 2 options:
Use the web server application to share state information
Use the Java-to-Javascript communication using JSObject as indicated at http://java.sun.com/products/plugin/1.3/docs/jsobject.html
Honestly, option number 2 comes with so many caveats, that I would never use it unless you had complete control over browser and Java versions on all potential users' systems. Even then, I'd be concerned of an update to something breaking it.
Basically, option number 1 leaves you with the Applet and the Javascript/HTML polling the web server (Rails) periodically to see if there are any updates or requests that they need to respond to for data exchange. If the applet is updated by the user, it sends a message to the web server via a URL request/post and the next query (probably via an AJAX-like call) by the web page will see the new data and the web page will be updated with it.
I hope that helps.
Two really great answers. I appreciate them a lot, thanks!
Reading your posts made me realize that the best choice is to use HTTP-requests to Rails REST interface. However, I see some downsides with this approach. But I don't see any better solution to it. One feature the applet should have, is to be able to browse and search in all products, which can be quite many. Sending a HTTP-request for each search will be expensive. Maybe I could solve this by loading all products when the applet starts. Then the browsing and searching would be fast. Or maybe do some nice caching. So once they are found, I don't fetch them again.
About not finding lots of information about this on the net. I see your point monceaux. But... I still think that there should be more. I mean, in my situation I would really like a Rails specific library that helped me send requests to correct urls. To bad Java is not that dynamic though. Kind of hard to do some stuff automatically, like in Ruby and Rails. Maybe I'll write a small library for this. I mean, I must write it anyway. So why not make a library of it? Some people might have use of it.

Categories