In a company I used to work at we were developing a midsize web application that we built using maven. Build time was 5 minutes and resulted in a ~70Mb .war file. This lag was very painful when it was time to debug, and by the time the build was finished I would sometimes find myself trying to remember what I was working on, at the same time having descended into playing Tetris (or occasionally Barrage). Not to say that there aren't medium to large apps that must take their time to compile, but I think in our case we had overcomplicated things for ourselves.
Nowadays for building pagegoblin I am using ant (I like it better personally), and build time is 5 seconds. Yet even this is too slow when developing. I would like to make changes in eclipse and be able to instantly test the results in my browser, before my mind wanders off to visions of lattes.
To achieve this I am using an embedded jetty server.
public class EclipseMain {
public static void main(String[] args) throws Exception {
Server server = new Server();
Context context = new Context(server, "/", Context.SESSIONS);
// This allows me to have cookies that work over subdomains
HashMap map = new HashMap();
map.put("org.mortbay.jetty.servlet.SessionDomain", ".localhost.localhost");
context.setInitParams(map);
// I am using both http and https in my app and want to test both
Connector connector = new SelectChannelConnector();
connector.setPort(8080);
SslSocketConnector sslConnector = new SslSocketConnector();
sslConnector.setPort(8443);
sslConnector.setKeystore("/path/to/my/keystore");
sslConnector.setPassword("wouldntyouliketoknow");
sslConnector.setKeyPassword("wouldntyouliketoknow");
sslConnector.setTruststore("/path/to/my/keystore");
sslConnector.setTrustPassword("wouldntyouliketoknow");
server.setConnectors(new Connector[] {connector, sslConnector});
// enable persistent sessions, so we don't need to relogin after restart
enablePersistentSessions(context, "/home/manuel/.jetty_test");
// Using my own jurlmap library here
context.addFilter(new FilterHolder(new GoblinDispatchFilter()), "/*",
org.mortbay.jetty.Handler.REQUEST
| org.mortbay.jetty.Handler.FORWARD);
// Static files such as images, css
context.setResourceBase("web");
// Serve static files
context.addServlet(DefaultServlet.class, "/");
// Server is ready to start
server.start();
}
public static void enablePersistentSessions(Context context, String folder) {
File file = new File(folder);
if (!file.exists()) {
file.mkdirs();
} else if (file.isFile()) {
throw new RuntimeException("Session location not a folder: " + folder);
}
final HashSessionManager manager = new HashSessionManager();
manager.setStoreDirectory(file);
context.getSessionHandler().setSessionManager(manager);
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
manager.saveSessions();
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
}
}
If you are not using JSP then you just need to add these three libraries from the jetty distribution to your project classpath:
jetty-6.1.14.jar
jetty-util-6.1.14.jar
servlet-api-2.5-6.1.14.jar
With this setup it takes about two seconds between making changes and being able to test the results. Just edit your code and run EclipseMain as a normal application (in eclipse Run As Java Application). I have configured persistent sessions which means I don't even have to log back in to my app after every server restart, I just hit refresh and I am right back where I left. Coding is fun again!
Whether you are trying to make your app more RESTful or just keeping up with programming fashion, clean urls are essential in modern web applications and for good reasons.
Bad => /member.jsp?username=tastychicken&view=blog&sort=hot
Good => /member/tastychicken/blog/hot
Why does this matter at all?
Your app looks more professional and by paying attention to details such as your urls you will give people the impression that your app is rock solid, well designed and in general that you know what you are doing. Assuming of course that the rest of your site looks as good as your neat urls...
It is easier for people to remember your urls and navigate to them manually. According to some research (can't remember the exact reference, just google it if you don't believe me), people spend as much as 24% of their time on a search results page looking at the returned urls, and are more likely to click on clean and informative urls than messed up ones.
It may matter for SEO (opinions differ on this one).
Plenty of other reasons explained in a multitude of related published articles so if you want more google away.
So if you are writing a site in java how do you go about implementing such urls for your app? There are several ways:
You can do it the old fashion manual way, like it was done for centuries.
You can create a filter in which you manually parse urls and forward to servlets or jsp pages for the action.
This becomes repetitive and unmaintainable very quickly.
You can use apache's mod_rewrite.
And yet there are times when you would like to stay completely in java rather than having a part of your application (the url structure) stored in a completely separate and unrelated place. Plus maybe you don't want or can't run apache on your live setup for some reason.
You can use an existing library such as UrlRewriteFilter which implements in Java the functionality of apache mod_rewrite.
This is a very good and powerful tool, and yet, I still prefer something that is more directly tuned to the single goal or creating clean urls, which would avoid multiple lines of xml configuration per url mapping (as it is a well established fact that xml is only good for sexual deviants), and would give me even more help with handling parameters.
To address this problem i wrote a small library called jurlmap. It was originally part of a framework I created to implement this website, (that is the website you are looking at right now). However I don't yet feel prepared to inflict another web framework on the world at this point, so I am releasing this as an independent library.
Some features of jurlmap are:
Here are some url pattern examples:
protected void configure() {
// In this pattern $ means a string, which when matched
// is bound to parameter `Username` and control forwarded to profile.jsp
// Parameter will be accessible via request.getParameter()
forward("/profile.jsp", "/profile/$Username");
// Here % means integer pattern and * means until end of the pattern.
// Binds integers to parameter ArticleId and forwards to article.jsp
forward("/article.jsp", "/article/%ArticleId/*");
// When matched will send a redirect back to browser and parameters
// are appended to query string so in this case the target will
// be `/servlets/profileservlet?Username=...`
redirect("/servlets/profileservlet", "/member/$Username");
// On match creates an instance of LoginPage and calls it's service method
// LoginPage class implements com.pagegoblin.jurlmap.Page.
// If it is annotated with a @Deploy(url) annotation
// the we don't need to pass a url to the deploy method.
// In this case parameters are bound to bean properties or fields
// of the newly created LoginPage instance.
deploy(LoginPage.class);
}
Detailed info and more advanced use cases can be found in the manual.
Enjoy.
This is small tutorial for drawing avatars such as the one used in this site. You will need a vector drawing program (I use inkscape a very nice and free program) and know the basics of how to use it.
First of all we start with the eyes.

Now we just copy this and we have two eyes.

For the head we do a big green circle and fill it with a radial gradient from green to very light green. The center of the gradient is set to the top left of the circle to represent the glow. We also paint a semi-transparent small circle in the center of the gradient to put more accent on the glow.

We place the eyes and the goblin is almost done, we just need ears and a mouth. The ears are simple, we start again with a circle and cut a part away by difference with another circle. We use the edit paths tool to make the shape more ear like and we fill it with a gradient. The ear is done.
The mouth is nothing more than a small circle filled with a gradient.
You can easily make variations of this to draw other creatures such as cats, dogs, pigs and gremlins.
Lets add some totally useless scanlines to the final picture (after exporting it to a painting program such as the gimp), for no other reason but simply to show how much we love our old Amiga.

And there you have it.