You are currently browsing the category archive for the ‘Programming’ category.


lazy summer

Originally uploaded by pixietart

I wrote a tiny and very handy JMS drainer in JRuby with Spring at work, but I got fed up with running it from a command line because I am lazy.

So I wanted a web interface to run a drainer in background. Since I got JRuby on Rails in Tomcat running, I checked out BackgroundDRb only briefly, or not harder enough to get it working. To be honest, I could not figure out how I run a JRuby script as task.

Anyway, I came up with a better and simpler solution. I don’t need a fully featured background tasks management for this. I don’t need to persist tasks nor schedule tasks. I don’t care if tasks were terminated in the middle. The only things I need are:

  • Run a task from a web form
  • Show running tasks

I played with JSON and Jetty in JRuby before and found that combination very easy to develop. I have also learnt jQuery to work with JSON at client side recently. So I have used them to implement the above the followings.

  • Make a standalone JRuby task class runnable in a Java thread
  • A servlet in Jetty in JRuby with POST to execute a task in a thread and store the task instance in a global array and GET to return a list of running tasks of their status in JSON.
  • A default servlet in Jetty in JRuby to serve static content, i.e. one HTML page with css, javascripts and images
  • Use jQuery Ajax to load a JSON from the local servlet and populate the task list table dynamically.

That is simple and works well. It scales, too. 20-odd JMS drainers can run in one JVM. The execution is faster and save loads on the server.

I might post sample codes here if anyone is interested in.

Advertisements

la vía láctea

Originally uploaded by sanabria

Simon Willison’s blog post made me try Comet finally. The Jetty and Dojo demo has worked without any hassle. Simon said:

The entire application took less than an hour to put together, which I think is a testament to the quality of the Bayeux implementation present in both Jetty and Dojo. […] Comet is probably about 90% of the way to being usable for mainstream project.

So I have decided to give it a go in my new experimental monitoring project and got a core feature working – a RESTish webservice being able to publish and cache a message and retrieve the latest message from the cache on top of Comet in Jetty and Dojo. Bayeux’s channel names are used as URIs in REST and keys in the cache.

What I wanted to archive with this feature is to mashup monitoring data from various tools, Nagios, Ganglia, etc. by server push. Even a simple chat can be in the same page!

First, I have replicated the demo into a webapp war and deployed it in tomcat 6.0, in which process I have learnt how it works more in details. Basically what I need is to deploy a Jetty’s Continuation Servlet, which does all server side magic for you.

I have chosen MemCached to cache Bayeux’s messages which are JSON objects.

The most difficult part so far was hooking the caching function into the Jetty Cometd Servlet. First, I tried DataFilter, but I can’t get the real channel id as I use a wildcard channel “/**”. It always returns the root channel “/”. Next, I tried BayeuxService used in the echo demo, but it does not allow to subscribe a wildcard channel. So I ended up adding a simple server side client which updates the cache on deliver method in Listener interface.

The RESTish webservice servlet, mapped to /galaxy/*, serves the only 2 methods, the HTTP GET to return the last Bayeux’s JSON message on the channel named by getPathInfo() and the HTTP POST to publish posted data onto the channel named by getPathInfo(). For example,

% curl http://localhost:8080/galaxy/nagios
{“channel”:”/nagios”,”id”:”5″,”data”:{“status”:”CRITICAL”}}
% curl -d “status=OK” http://localhost:8080/galaxy/nagios

At client side I use jQuery with Dojo and its color animations to notify a changed value by changing the background colors. It loads the initial data by getJSON on the galaxy servlet and updates the data by cometd subscriber.

So far so good.


Super Ray

Originally uploaded by *MSM*

I have a Rails 1.2.3 application running in JRuby 1.0.1 on Tomcat 5.5.9 at work. The application itself is not mine (actually Tim‘s), but I helped him to run it in JRuby on Tomcat so that we can utilize the existing infrastructure at work.

After I’ve got the Rails 2.0 development tools working, as recommended, I have upgraded the application to Rails 1.2.6 and successfully run it in JRuby 1.0.3 on Tomcat 6.0.10 with ActiveRecord -JDBC 0.7 and goldspike 1.4. I haven’t seen any deprecation warnings so far, which is a good sign.

Here are some short tips (and notes for myself) so far:

  • As mentioned in Nick’s post, for Rails 1.2.x to use the AR-JDBC 0.7, you need to add the followings into “config/environment.rb” in the usual spot above the “Rails::Initializer”, for example

require ‘rubygems’
RAILS_CONNECTION_ADAPTERS = %w(jdbcmysql)
gem ‘activerecord-jdbcmysql-adapter’

  • Use the absolute path with RAILS_ROOT when accessing a file directly. This is because the working directory of the webapps is different from when the rails app is running in WEBrick or mongrel.
  • Consolidate logging into one stream by configuring the both Tomcat and Rails logging to STDOUT. In “config/environment.rb” insert the followings right after the “Rails::Initializer.run do |config|” line. I also disable the colorized log messages to make them readable in the Eclipse console window.

config.logger = Logger.new(STDOUT)
config.active_record.colorize_logging = false

  • I don’t use the goldspike plugin that provides tasks to package up a web archive. Instead, I use the static web.xml without “jruby.home” and “rails.env params” to make the web archive deployment environment independent. Instead I set JRUBY_HOME and RAILS_ENV.
  • In general, use Gems On Rails – “vendor everything”, which allows you to push dependent gems into your rails app thus ensuring your application will be guaranteed to work when deployed. This makes the deployment much easier even at work place. My team provides application hosting environments where only core gems are installed.

See also:



JRuby on Rails in Tomcat inside Eclipse (Part 2)
Originally uploaded by Lilly

It was only a few weeks ago when JRuby 1.0.2 did not work well with Rails 2.0.1. Now JRuby 1.0.3 is out and Rails 2.0.2 is out, too.

So I have tried this again – JRuby on Rails in Eclipse IDE with WebTools Platform and RadRails.

Since RadRails 0.9.1 which has fixed compatibility issues with Eclipse 3.3 was out in November, I have upgraded Eclipse to 3.3.1 with WebTools Platform 2.0.1. I have also upgraded Tomcat to 6.0 as WTP 2.0 supports it.

ActiveRecord-JDBC 0.7 and GoldSpike 1.4 are just out, too. Basically I have upgraded everything and they have worked well together. I am going to upgrade or maybe re-write a few of my old rails apps in this development environment. How exciting!

See also:



The avenue in mist and sun

Originally uploaded by algo

Spring JMS has made JMS easy. JRuby makes it even easier.

I have used the OpenAdaptor as JMS clients for benchmarking and supporting tasks. With many ready-built components I can do most of things I need to do, but sometimes I can’t do simple things like sending a sample message in a file repeatedly for benchmarking unless I do a bit of java programming to extend the existing components.

The Spring’s SimpleMessageContrainer works well as a simple subscriber like for benchmarking or draining messages. I just needed to set the AutoStartup to false and set a JRuby implementation of the MessageListener to the SimpleMessageContainer bean programmatically before starting it up.

However, the JmsTemplate falls short on the publishing side, i.e. it opens and closes a session every time it sends a message. James Strachan has more on that. So I needed to create a session and a publisher in JRuby. Even so, it’s still easy as the Spring does the rest.

OpenAdaptor’s JMS Peek utility is useful as a diagnostic aid especially for Topic as it does not have a browsing interface like QueueBrowser. There were a few support cases in the past where users wanted to peek more than one messages. Not surprisingly, it was easily done in JRuby with Spring JMS. Fisrt, I tried to set the SessionAcknowledgeMode of SimpleMessageContainer to CLIENT_ACKNOWLEDGE, but it turned out that the SimpleMessageContainer called acknowledge() on Message. So, like the JRuby publisher, I have created a durable subscriber to receive a number of messages without acknowledging them.

Here are source codes of the above JRuby scripts. They are good enough to get simple things done quickly and simply. That’s why I love JRuby.

Related Posts:


Originally uploaded by Lucee.

In my previous post, I’ve re-written my old Java JMX client program in JRuby with Jetty.

In other area of my old Java program, I chose the data-push model, calling a set of JMX commands periodically and publishing data onto JMS, because I did not want them called too much frequently by accident. It has worked well, but there are a few things I wanted to change like, 1) It can’t run another instance for redundancy, 2) it’s not simple to get data because of JMS.

So, this time I’ve chosen the data-pull model with embedded HTTP servlet container jetty, implementing JSON webservice.

I also chose data caching without database backend in the JBoss webapp that subscribes to the JMX data on JMS. I admit I made a wrong decision on that. The data became stale from time to time and the JBoss server needed to restart to resolve the problem.

This time, as you would expect, I’ve chosen MySQL since I am thinking to rewrite the webapp in Rails.

The point of this post is how I gather data for a Rails application.

What I need is to gather data every minute. There are a few ways to run background jobs in Rails, but there is a better and simpler way to do that, which is running Rake tasks using Active Records from Cron. There is a great tutorial on that from Rails Envy.

Each task takes 15-20 secs to complete. Anything could go wrong and more than one task would run at once, which would make the problem worse. How can I prevent this? Lockrun comes handy here. Lockrun serves as a protective wrapper and it insures that another instance of the same command is not already running. My co-worker Phil has been using this for his applications for sometime now.

Related Posts:


and i’ve been workin’ like a dog
Originally uploaded by manyfires

JRuby has proved (to me at least) to be really powerful in prototyping and learning Java APIs. A few weeks ago I started thinking to rewrite one of my old Java programs in JRuby. I wrote that Java program as part of learning Java programming (so it’s not as good as I hoped) and I am no longer interested in maintaining it in Java since I’ve learned JRuby. I also thought that I made it a bit complicated to maintain. So I am hoping to simplify it by rewriting in JRuby and Ruby. It will be a challenge for me since I am still learning Ruby, but I hope I enjoy it.

The program calls various JMX APIs on a JMS server periodically and publishes outputs in XML onto JMS. The JMS server has a JMX Console, but I needed a web application for a consolidated view to monitor a number of JMS servers and clients on them.

It was not difficult at all to rewrite one part of the program, calling JMX APIs in JRuby. However, I thought twice about the data transport. Although it’s possible to use JMS in JRuby, inspired by Joe Gregorio’s RESTful JSON, I have decided to use JSON as data transport format this time. Bearing in mind the further integration with the current infrastructure at work, I have also chosen Jetty as HTTP server. Thanks to Keith who has shared his experience in running Jetty in JRuby. Jetty has JSON libraries built in, which is a bonus.

During the development, I’ve found Eyal’s JSON Viewer handy (even I have to cut & paste JSON data from cURL output) since browsers do not render response which content type is “application./json”, while you can view unformatted JSON with Firebug’s network monitoring. Does anyone know anything like Michael Bolin‘s JSON Inspector?

So far I’ve got the RESTful JSON webservice working for some GET requests. Now I need to think about URIs mapping and implementation of other JMX functions I use. I will post follow-up if I find something worthy to post.

P.S. The photo is nothing to do with this post, but as always I love to attach a wonderful photo (and story, too) I’ve found in Flickr.

Related Posts:


Endtime
Originally uploaded by Batram

Have your application ever been blocked by Log4j logging? Ideally your application should be less dependable on external logging services, SMTPAppender or JMSAppender, etc, but you need one to monitor important events remotely.

The AsyncAppender lets you log events asynchronously. It will collect the events sent to it and then dispatch them to all the appenders that are attached to it. You can attach multiple appenders to an AsyncAppender, but I won’t do that. The AsyncAppender uses a separate thread to serve the events in its buffer. The default buffer size is 128 and the blocking is set to true, which means that the logging is blocked when the buffer is full. I don’t know why the default blocking is set to true. Reading the source codes, if it’s set to false, the logging won’t be blocked since events are summarized and discarded. I’ve got to test it.

I have used JRuby to test the AsyncAppender and found it very handy again.

First of all, I needed an Log4j Appender that runs a bit slow. So, I have created a very simple SlowAppender.rb, which is a subclass of Log4j AppenderSkeleton. You just need to implement the append method.

SlowAppender < org.apache.log4j.AppenderSkeleton
def append(event)
sleep 1
puts layout.format(event)
end
end

Since I can’t configure it in log4j.xml, I add it to an AsyncAppender programmatically in a test JRuby script.

logger = Logger.getRootLogger()
slow = SlowAppender.new
slow.setLayout(PatternLayout.new("%d{ABSOLUTE} %-5p [%c{1}] %m%n"))
async = logger.getAppender("ASYNC")
async.addAppender(slow)

Full source codes and the result of the test script are available here.

You may not like that some events are discarded, but ideally you should be notified by catastrophic problems with remote logging services before that. What’s important to you is that your application keeps working without being disrupted by other services.

You should also consider using StringMatchFilter to avoid sending unnecessary log messages to remote logging services. A flood of unnecessary logging messages will cause problems to remove logging services that are most likely shared with other applications.

A while back I came across RSSAppender and I think it’s a very simple way to retrieve and aggregate important logging events. How it works? Why don’t you test it in JRuby?


All Your Famous Friends
Originally uploaded by Thomas Hawk

I have waited for this news, JRuby 1.0.0RC3 Released – And This Is It!

I have already managed to run an example of JRuby on Rails in Tomcat with PKI at work. So what I need next was an application development environment and I’ve got JRuby on Rails running on Tomcat inside Eclipse IDE with Eclipse WebTools Platform and Aptana’s RadRails plugin.

I already have a Tomcat package coupled with JASS (Java Authentication and Authorisation Service) framework at work, which works nicely within Eclipse IDE with WTP. So, I just needed to install RadRails as a plugin to that. I can only use RadRails to develop a Rails app, but can’t run it in WEBrick because it calls Java JASS API functions to get out other information about the user. However, you can add it to a Tomcat server as an external web module (you can’t add this as a web module because it’s not a web project, but a rails project) so that you can run the Rails app with JRuby in Tomcat within Eclipse! Here is a short instruction.

  1. Download the Eclipse + WTP all-in-one package
  2. Install RadRails and configure it
  3. Create a new Rails project
  4. Create a WEB-INF folder with necessary files in the root of the project
  5. Create a new server (e.g. Tomcat)
  6. Add the Rails project as an external web module to the server. You just point the directory where the Rails project resides in and give a path like /projectname.
  7. Start the server
  8. Open a browser in Eclipse and access the webapp (screenshot)

Related Posts:

Archives

Blog Stats

  • 87,630 hits

Identitiy