Sinatra on Java

With JRuby and Warbler it’s possible to get Sinatra, or any WebApp based on Rack, running on a myriad of different Java application servers. There are of course gotchas when it comes to using Warbler with the many different app servers, so this is a definitive guide to everything you have to do to get a simple Sinatra app running on the various application servers.

Why Sinatra?

There are examples of how to get Rails running on Tomcat and Websphere floating around the web, but I find Rails overkill for small projects. With that in mind, it’s worth looking at how to get Sinatra running on java application servers. Besides the weight of rails, Sinatra is a nice, easy to learn framework.

Start by installing Sinatra and Warbler. You don’t have to be using JRuby to install Warbler, the install will download a gem of the jruby jars.

Install Sinatra and Warbler

Lets start by installing the required gems.

$ sudo gem install sinatra warbler haml

Haml isn’t strictly required, but the template I’m going to use has views generated in haml, so if you’re following the tutorial closely you’ll want to install it.


Create a project folder (and structure)

I usually keep a sinatra project template handy. So I’m going to clone my existing template off github. You can create a more minimal example than the one I’ll download, this will get the job done though.

$ git clone git://github.com/vertis/sinatra-example.git deploy_test

TODO: Details about the project


Check that our page is displayed

$ rackup

Go to http://localhost:9292/ and you should see our default page.

Generate the warble config

$ mkdir config && warble config

Lets look at the config file that was generated:

If you tried packaging and installing this now, it would fail miserably because, the ‘init.rb’ file would not be included. The generated warble.rb only includes the following

config.dirs = %w(app config lib log vendor tmp)

In addition to this the gems that we installed above would not be install. Here is same config with the lines we need (and the other cruft removed).

Package up the War file

$ warble

From here on in we’ll be looking at any gotchas, when deploying to the different Application Servers.

Deploy to Glassfish and test (effort: moderate – working: yes)

You can get Suns open source application server from http://glassfish.org. The current stable version of Glassfish 2.1.1, though Glassfish 3 is in active development. The installer comes packaged as a jar file. You can run the installer with

$ java -Xmx256m -jar glassfish-installer-v2.1.1-b31g-linux.jar

After accepting the license it should put all the files in a folder called ‘glassfish’ in the current directory.

$ cd glassfish
You need to run the following commands to finish the setup:

$ chmod -R +x lib/ant/bin
$ lib/ant/bin/ant -f setup.xml

Once the software is installed you can start the domain with:

$ bin/asaadmin start-domain domain1

And use either the admin console or the autodeploy directory to deploy the war file.

Glassfish now has a working copy of our application.

Deploy to JBoss and test (effort: n/a – working: no)

JBoss has a community and an enterprise edition. For the purposes of this test we’ll be using the community edition. The current stable version of JBoss AS is 5.1.0 GA. You can get a copy of JBoss from http://www.jboss.org.

Getting started is as simple as unzipping the archive and running:

$ cd jboss-5.1.0.GA

$ bin/run.sh

You can then use the admin console to deploy the application. One gotcha here, the first time I deployed the application using the console I got the following nasty message:

Application initialization failed: no such file to load — rack
from /opt/application_servers/jboss-5.1.0.GA/server/default/deploy/deploy_test.war/WEB-INF/lib/jruby-rack-0.9.5.jar/vendor/rack.rb:1
from /opt/application_servers/jboss-5.1.0.GA/server/default/deploy/deploy_test.war/WEB-INF/lib/jruby-rack-0.9.5.jar/vendor/rack.rb:22:in `require’
from /opt/application_servers/jboss-5.1.0.GA/server/default/deploy/deploy_test.war/WEB-INF/lib/jruby-rack-0.9.5.jar/jruby/rack/booter.rb:22:in `boot!’
from /opt/application_servers/jboss-5.1.0.GA/server/default/deploy/deploy_test.war/WEB-INF/lib/jruby-rack-0.9.5.jar/jruby/rack/boot/rack.rb:9
from /opt/application_servers/jboss-5.1.0.GA/server/default/deploy/deploy_test.war/WEB-INF/lib/jruby-rack-0.9.5.jar/jruby/rack/boot/rack.rb:1:in `load’
from <script>:1

Turns out that after some digging there is an open jruby bug about the issue -  http://jira.codehaus.org/browse/JRUBY-3935

I also did a bit of digging through the logs and found:

16:27:50,703 ERROR [STDERR] Warning: JRuby home “/opt/application_servers/jboss-5.1.0.GA/server/default/deploy/deploy_test.war/WEB-INF/lib/jruby-stdlib-1.4.0.jar/META-INF/jruby.home” does not exist, using /tmp

I’ve not managed to find a solution to this problem. I will revisit this at some point in the future. After googling a little it may be possible to just revert to a few older versions that seemed to work.


Deploy to Jetty and test (effort: easy – working: yes)

The current version of Jetty is 7.0.1.v20091125, though the version that comes as part of your Linux distro may not be so up to date. You can either install it using your favorite package manager, or if you’re on Windows get it from the homepage at http://www.mortbay.org

Once you’ve installed Jetty copy the generated war file to the webapps folder, and run:

$ bin/jetty.sh

You should be able to go to http://localhost:8080/deploy_test

Congratulations you now have a working copy of your sinatra app on Jetty.
Deploy to Tomcat and test (effort: easy – working: yes)

The current stable version of Tomcat is 6.0.20. You can either install it using your favorite package manager, or if you’re on Windows get it from the homepage at http://tomcat.apache.org

You shouldn’t have to make any changes to get our web app to work on Tomcat. Once you’ve installed Tomcat copy the generated war file to the webapps folder, and run:

$ bin/startup.sh

You should be able to go to http://localhost:8080/deploy_test

Tomcat really is the bread and butter of Java Application Servers, especially outside the Enterprise.

Deploy to Websphere and test (effort: hard – working: yes)

NB: Websphere 6.1.0.11 was the first application server I ever deployed Sinatra too, it failed miserably. I spent a long time debugging and playing with it to make it work properly. The biggest problem stems from the fact that the default way of using rack as configured by warbler doesn’t work.

Start by logging into the administration console, it should be something like – http://localhost:9043/ibm/console

Click on ‘Servers’ and when it expands select ‘Application Servers’. From here you can setup a new server instance that we can use for our testing. Call the instance something like ‘deploy01′. You can follow the default creation steps all the way through.

Once you have a server instance to test on, you can deploy a new application. The big gotcha as mentioned above is that you can’t use filters, the good news is that it’s quite easy to switch out the rack filters for a rack servlet. Rather than duplicate information that already exists, I’ll link to the place I learned to deploy warbler to websphere, http://clint-hill.com/2008/11/26/jruby-on-rails-and-websphere/.

Websphere is not the easiest application server to setup in general, but once you get it all configured it is fairly robust. Worth the effort if you want an application server you won’t have to restart constantly (as can be the case with Documentum on Tomcat).


Deploy to Weblogic and test (effort: n/a – working: no)

Setting up Oracle Weblogic 10.3.2 was nothing short of awesome. The install process is intuitive and speedy, though the size is quite large, at ~600Mb,  compared to smaller cousins such as Tomcat. There is a wizard that walks you through the process of setting up your first domain, what Tomcat would call an instance and Websphere would call a profile, once the software is installed. I chose the default options for everything and had a running Weblogic server in about 20mins (including download).

My previous experience with Weblogic, was the version bundled with Documentum D6SP1. I’ve found both that version and the current fully fledged Oracle version to be a joy to work with.

Once the installation process is finished you can find the administration console at http://localhost:7001/console, you can then login using the username/password you picked during installation.

From the admin console it is a simple matter of clicking on ‘Deployments’ on the left and then when the screen loads clicking ‘install’, browse to the directory with the deploy_test.war file in it and start the install.

You should now be able to access the deployed application at http://localhost:7001/deploy_test…

Application initialization failed: no such file to load — rack from C:/Oracle/Middleware/user_projects/domains/base_domain/servers/AdminServer/tmp/_WL_user/deploy_test/qwtgi/war/WEB-INF/lib/jruby-rack-0.9.5.jar!/vendor/rack.rb:1 from C:/Oracle/Middleware/user_projects/domains/base_domain/servers/AdminServer/tmp/_WL_user/deploy_test/qwtgi/war/WEB-INF/lib/jruby-rack-0.9.5.jar!/vendor/rack.rb:22:in `require’ from C:/Oracle/Middleware/user_projects/domains/base_domain/servers/AdminServer/tmp/_WL_user/deploy_test/qwtgi/war/WEB-INF/lib/jruby-rack-0.9.5.jar!/jruby/rack/booter.rb:22:in `boot!’ from C:/Oracle/Middleware/user_projects/domains/base_domain/servers/AdminServer/tmp/_WL_user/deploy_test/qwtgi/war/WEB-INF/lib/jruby-rack-0.9.5.jar!/jruby/rack/boot/rack.rb:9 from C:/Oracle/Middleware/user_projects/domains/base_domain/servers/AdminServer/tmp/_WL_user/deploy_test/qwtgi/war/WEB-INF/lib/jruby-rack-0.9.5.jar!/jruby/rack/boot/rack.rb:1:in `load’ from

Clearly thats not going to be the case though. This issue is very similar to the error message received for JBoss.

Conclusion

Not a bad scorecard really. Of all the Java application servers that I tested, only JBoss and Weblogic proved to be a problem. I’ll be retesting these two periodically to see if support has been improved (there are open tickets with JRuby). Until then I hope that this has been useful.

Lotus Notes 8 Development

I’m finally finished beating my head against the wall trying to get drag and drop to work in Lotus Notes 8. It turned out to be a good deal less friendly than I expected.

The actual core of drag and drop listening is stock Eclipse RCP. That’ll trigger off the events as expected, but I found that it wasn’t passing anything across. After digging down as far as I could to see if it just wasn’t processing the transfer properly, I concluded that it was a dead end.

The old way of dealing with this would have been to use NotesUIWorkspace to get the currently selected document. That was never implemented in Java (which is probably because it’s not needed). Because of the eclipse architecture, it is strictly possible to access whatever you want using the standard eclipse classes. Thankfully, we don’t even have to worry about going this deep, I stumbled across an open source plug-in called Formul8 by Jeff Gilfelt. Jeff’s plug-in allows you to execute formulas in the context of the currently selected Document(s), which is similar to what I needed.

Under the hood Formul8 is powered by ‘com.ibm.lotuslabs.context’. Armed with that discovery, I headed back to google, finding this post  about how to use ‘lotuslab.context’, in addition, it also links to a copy of the source code (yippee!).

JRubyOnRails for the enterprise

I believe that JRubyOnRails is paving the way for ruby and rails to be integrated into enterprise rather than being the sole domain of cutting edge developers. Perhaps its important that enterprise realises the power of rails or perhaps not (it might be better to keep it for ourselves). Regardless the ability to run ruby on rails applications on Java Application Servers is a big step towards acceptence in the enterprise.

For those that aren’t familiar with this ability google ‘warbler’  and run through the tutorial. It is a little more complex to get a larger project to run on a Java Application Server but not so much that would deterr people. It will likely be a long path before its a mainstream technology but it’s a good first step.

It’s also not necessarily a good thing to be tied to java, but when enterprise is so slow to embrace new technologies and better ways of doing things it is important to compensate to some degree. Not making them completely replace the Java application server that they paid to much for in the first place may make that admission and acceptence a little easier.

UPDATE: I’ve since started following @headius on twitter, the primary force behind JRuby. He is outstanding, and his belief in getting ruby accepted in the enterprise is inspirational.

Native Java with GCJ and SWT

The ability to compile Java to native code has existed for a while in the form of GCJ, though for the most part it has been overlooked due in part to the incomplete Swing/AWT implementation. Knowledge about how to use GCJ for native compilation is a bit vague. When you first start using GCJ as a real alternative to the Sun JDK it’s difficult to get an idea of exactly what GCJ is capable of doing.

Getting GCJ

If you are a linux user most distributions come with GCJ as either preinstall or one that you can easily install with your favorite package manager. If you are using Windows then your best bet is to use the packages found that http://www.thisiscool.com/gcc_mingw.htm

Mohan Embar, the author of the ThisIsCool website has created several builds of the MingW GCJ that can be easily installed. Additionally he has built in SWT and SwingWT support to some of the builds. Keep in mind that shared builds, and the creation of ‘dll’ files is not supported under the 4.x series of GCJ found on this page.

For the remainder of this build we will be using the latest GCJ found on this page, which includes the eclipse merge branch from the GCC SVN, the best thing about this is that it gives support for Java 5 features.

Basic Native Compilation

The first step is to create a basic ‘Hello World!’ application, to demonstrate compiling an application.

public class HelloWorld {

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

System.out.println(“Hello World!”);

}

}

Assuming you’ve added the gcc-ecj\bin\ folder to your path, you can then compile the application using the following command:

Gcj –o Hello.exe –main=HelloWorld HelloWorld.java

You can then run the resulting EXE just as you would any other application.

Basic Windows Application

If you tried running this application from windows (and not from the command line) you wouldn’t have seen much, just a black window flashing up and then closing again. Let’s do a basic Windows application so that you can begin making your masterpiece. This is accomplished using SWT. We will start by creating a ‘HelloWindows.java’ file. You can view the source with Listing 1

We will then compile the source in two steps.

gcj –classpath .; lib\swt.jar -c -o HelloWindow.o

This creates a object file that can be used in the next step to create a working java application.

gcj –main=HelloWindows -mwindows -o HelloWindows.exe HelloWindow.o lib\swt.a

You will still need the DLL files that came packaged with thisiscool gcj in order to run the application but it should create a small windows with ‘Hello Windows’ in the title bar; not very exciting I will admit, but it demonstrates a working windows application.

Notes about this step:

The ‘swt.jar’, ‘swt.a’ and ‘swt*.dll’ files can be found as a part of the thisiscool download, you either need to move them into the same directory as your project or provide a full directory in the adequate place. The dll files should be placed in the same directory as the build .exe file.

More Complex Projects and Libraries

One of the things you may not know is that GCJ can not only work from source files, but also from class and jar files. This is particularly useful if you want to do more complex projects that use existing libraries such as the db4o-6.0-java5.jar file gotten from http://www.db4o.com/.

First create the object file, using the command:

gcj -c db4o-6.1-java5.jar

This creates a file, db4o-6.0-java5.o; we then use ‘ar’ tool to create a static library:

ar -r libdb4o.a db4o-6.1-java5.o

This library file can then be combined into our future projects much the same way as jar files are used in current java projects.

Using Our Shared Library

Not to put the work to waste lets compile a project using the DB4o library that we created in the last part. The source code is too long to paste into the body of the article so I’ve included it in a zip folder so that you can try it later. Let’s start by compiling the source to object files as before:

gcj -classpath .;lib\db4o-6.1-java5.jar;lib/swt.jar -c HelloDb4o.java Account.java

Then we take the library we created before and combine it with the main project (also adding the SWT library):

gcj -o hellodb4o.exe -mwindows –main=HelloDb4o HelloDb4o.o Account.o lib\libdb4o.a lib\libswt.a

You now have an application that will display the record from the database.

Final Notes

Size is often one of the pet complaints when people compile using GCJ, I would encourage people to check out UPX (http://upx.sourceforge.net/).

The source listings here in were done quite hurriedly; particularly the last application would need a good deal of work before it was functional in a useful way. DB4o is a topic for several books, I strongly encourage you to take it out for a test drive.

In order to catch bugs it is in the interest of the developer to remove the ‘-mwindows’ option from the final build. This causes a command line window to be created behind the main screen to which printed exceptions are sent. Alternately and perhaps more correctly logging to file could be implemented.

Finally, it is possible to use Ant and other build tools to make building projects easier, you will find details in the resources on how to accomplish this. For the purposes of explanation I have chosen NOT to use these tools in this article.

Resources

The following were useful guides/tools as I was getting started with GCJ Native Development.

Create native, cross-platform GUI applications – http://www.ibm.com/developerworks/library/j-nativegui/

Create native, cross-platform GUI applications, revisited – http://www.ibm.com/developerworks/java/library/j-nativegui2/

How to compile Java application to native code, for example to Windows EXE file – http://robohobby.s41.eatj.com/java_to_native_code_exe.jsp

DB4o Object Oriented Database – http://www.db4o.com/

The Ultimate Packer for Executables – http://upx.sourceforge.net/

ThisIsCool GCJ – http://www.thisiscool.com/gcc_mingw.htm

Secure Your Java Source Code

I want to quickly run you through the pitfalls of using java as a programming language when it comes to the security of your proprietary source code. One of the problems with Java is the relative ease with which you can reverse engineer the source code. In fact there are numerous tools out there which will very simply and quickly take your project and turn it into a VERY readable document. For the purpose of instruction we will first decompile the example project, comparing the original source with what comes out the other end.

We will repeat this process (if possible with the techniques that can be used to protect your source code).

The Jad Decompiler + Front End Plus

As mentioned above there are plenty of available decompilers, however JAD is a free and open source alternative that is perhaps the most popular option out there. Coupled with Front End Plus, a GUI that is designed to use JAD, you can very easily open and decompile the Java source.

This is a decompile of my own Arms Conversion program, as you can see, while you may have to do a little work if you wished this code to recompile, the intent of can be seen very clearly.

Obfuscation

Obfuscating the source code is one method that is often used to protect Java code. It refers to deliberately making the code harder to read. Rather than a cracker getting back a function called IDoSomethingCool (String name) … they instead might get something back like dadaba3 (String adabc9989).

This doesn’t stop the cracker from reading the code, nor from it working if they chose to recompile it. However it does make it MUCH more difficult to determine the intent of the code. Are the naming conventions that programmers use to determine what information is being stored/parsed/manipulated

I should be clear that this is far from a full proof solution. With time and dedication it is still possible to rebuild the original intent. However Obfuscation is a big step towards making it a waste of time (it may cost less to just write the application from scratch).

There are plenty of tools available that can be used to obfuscate the code.

Native Compilation

By far the best option for protecting the source code is the ability to natively compile the application. While there are potential issues to be addressed in order to implement native compilation it has the benefit of making the reverse engineering infinitely more difficult.

While NO application is truly immune to reverse engineering, going from compiled code back to useable source code requires a very specialized ability, and a depth of knowledge about computer programmers that is possessed by few.

Native code compilation is discussed in more detail in another document, which deals with additional features that are available, and also the potential problems with natively compiling your applications.

Recently I’ve been doing quite a bit of development in Java. Of the many languages that I’ve played with and used I find Java to be one of the most functional programming languages out there. There are plenty of factors that have helped me choose Java as my primary programming language, and while I’m not under the illusion that java is the ‘monkey wrench’ of the programming world, its still an invaluable tool.

I’ve been around programming languages for the last 6 – 7 years, in that time a lot has changed. The software industry has matured in its approach to programming, and the fundamental building blocks that make up the software industry have matured as well. Gone is the time when you needed a PhD to understand the complexities of computer programming. This is not an article about the many different languages; this is not even an article about how Java is better than ‘x’ language. This is simply an article about the features of Java that slipped it into my toolkit.

Native Graphics Support

The first thing that usually pops into mind when you want to convince someone about the superiority of java, is the fact that it’s a compile once run anywhere language. Honestly though I find this less useful than you might think. What I do find useful is the fact that with very little research you can write a graphical user interface for an application. I find the graphics support for Java to be logical, where so many other graphics libraries are not. While I’m not overly fond of the layout managers that Java provides, I can appreciate the fact that they’re there if I do ever find a use for them.

Excellent Database Support

This was one of my primary reasons for moving to java in the first place. If you’ve ever tried to get MySQL working with (Visual) C# then you’ll know what I’m talking about. The JDBC makes connecting to whatever database a dream, if your program is well written you can even switch database backend without to much trouble.

Eclipse IDE

If you haven’t tried Eclipse then you don’t know what your missing out on. While its certainly not solely dedicated to Java it’s a very flexible and well designed tool that will help you get your work done. In addition to being a useful portal to the Java language, it is also a driving force in making Java into more than just the pet project of Sun Microsystems. Take a look at SWT, which was originally developed by IBM and is distributed as a part of eclipse and you will begin to understand.

Lack of Deployment Options

This is one of the fundamental failings of a lot of programming languages. Running a java program relies on the operating system already having a copy of the Java Runtime Environment (JRE) installed. If its not then you won’t be able to do squat, additionally there is no way of knowing whether the version of Java that you’re programming in, and that has the features you want is installed on the client.

You fall back into the same rut that the old VB programs had with missing DLL files. There is no simple way of installing both Java and the given Application in one easy step. Additionally you are held hostage by the fact that you require certain environment variables to be set correctly for the java program to run (JAVA_HOME, CLASSPATH). This is all well and good but it’s just more overhead for the programmer to worry about when they need to do a large scale deployment of an application that they’ve developed.

GCJ bridging the gap

One of the baseline flaws with Java is the fact that it is interpreted (from bytecode) at runtime, and as such relies on the JVM. More importantly it means that it runs slower on CPU intensive processes like md5 hashing for example. GCJ is the GNU Toolkit’s answer to the fact that Java is not open source. It is in effect a complete replacement for Sun Java. More importantly it provides support for compiling Java directly as an Executable freeing it from the reliance on the JVM.

The speeds generated when running is GREATLY improved, to close GCC/G++ levels, and more importantly the deployment is less of an issue. You do lose the fundamental portability that is gained with Java classes, but there is no reason you can’t provide the class files and just install GCJ (rather than Java) to allow the class files to be converted into executables.

THE only place where GCJ is still lacking is the area of AWT/Swing; the developers are still working on adding the support necessary to support the windowing toolkits. Incidentally they are looking for help in this area if any of you programming gurus want to give up your spare time.

Conclusion

The bottom line with Java is that it is a functional and practical language. The fact that Sun is still holding the reins is regrettable because it’s inhibiting a language with otherwise HUGE potential from maturing. The compile once, run anywhere is less useful than ‘write once / compile (& run) anywhere’ this subtle difference is where Sun missed the boat. The matter of compiling different copies for different operating systems is trivial when you consider the fact that doing it the way they are cripples the speed of the language.

Other than that Java is a great choice because it’s a language that’s flexible enough to be used on plenty of different operating systems. You do lose a certain amount of control over the low level functions; however this particular beef has been adequately dealt with in the form of JNI.