Creating a simple java web app using IntelliJ IDEA and setting up remote debugging

I had to get this setup up and running at work, thought it’ll be a good idea to jot it down here. The first step is to install IntelliJ IDE from here. I installed the ultimate edition which has a free 30-day trial, but the steps below should work well with the free community edition as well (looks like this does not work on community edition). We’ll be hosting the app on Tomcat server (running on a remote machine) so go ahead and install it from here. I installed version 8 using the windows service installer. And of course, since you’re developing a java app make sure you have the jdk installed.

Launch IDEA and create a new project, we’ll call it SimpleJavaWebApp. Select Java Enterprise and Web Application. Make sure the project SDK is set correctly and application server is set to the version of Tomcat you installed.

image

Let’s add a Java servlet to the project. Right click on the src folder in project explorer and select New –> Servlet, give the servlet a name and add it to the project.

image

Open MyServlet.java and copy paste the below code in the doGet() function,

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        response.setContentType("text/html");
        response.setCharacterEncoding("UTF-8");

        try (PrintWriter writer = response.getWriter()) {

            writer.println("<!DOCTYPE html><html>");
            writer.println("<head>");
            writer.println("<meta charset=\"UTF-8\" />");
            writer.println("<title>MyServlet.java:doGet(): Servlet code!</title>");
            writer.println("</head>");
            writer.println("<body>");

            writer.println("<h1>This is a simple java servlet.</h1>");

            writer.println("</body>");
            writer.println("</html>");
        }
    }
}

If you are seeing an error which says “java: try with resources is not supported in –source 1.6”, go to project properties by right clicking on the project and selecting Open Module Settings, select Project on the left rail and change the Project Language Level to 8.

Let’s modify index.jsp to put an entry point to our servlet,

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title></title>
  </head>
  <body>
    <h1>Simple Java Web App Demo</h1>
    <p>To invoke the java servlet click <a href="MyServlet">here</a></p>
  </body>
</html>

Modify web.xml file and put the below servlet configuration in it, the url pattern is case sensitive so make sure it matches your servlet name exactly,

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">

  <servlet>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>MyServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/MyServlet</url-pattern>
  </servlet-mapping>

</web-app>

Go to Build –> Rebuild Project, and make sure the project is building fine. Let’s now package our application in WAR format (Web application ARchive) and deploy it on a machine running Tomcat.

Right click on the project and select Open Module Settings, click on Artifacts on the left rail and select + to add a new artifact type. Click on Web Application : Archive and select the project name.

image

Now when you build the project you will find file SimpleJavaWebApp_war.war generated under \SimpleJavaWebApp\out\artifacts\SimpleJavaWebApp_war folder.

Let’s deploy our app now, go to the machine where you installed Tomcat (it could be the same machine too), and under the Tomcat installation directory, copy the above WAR file under the webapps folder. For me the path is “C:\Program Files (x86)\Apache Software Foundation\Tomcat 8.0\webapps”. To make sure your app is working as expected, navigate to http://localhost:8080/SimpleJavaWebApp_war/ and check if the web page loads up correctly.

image

So the bulk of the work is done. We’ve created a simple Java web app, added a java servlet to it, deployed the application on Tomcat and made sure that the servlet code is invoked correctly. We’ll now look at how to remotely debug this app. This is useful is cases where you have the application running on a server, and your code and source enlistment are on a different machine.

To get remote debugging working, we need to instruct Tomcat to start the JVM in a “debug” mode and then attach to the JVM from IDEA.

Open Tomcat server properties, go to the Java tab and add the below entry under Java Options (make sure you add this in a new line),

-agentlib:jdwp=transport=dt_socket,address=1043,server=y,suspend=n

image

Restart the server and check if you can access SimpleJavaWebApp from a remote machine. I setup the server and deployed the war file on a different machine and navigated to below URL to check,

image

We now need to create a debug configuration in IDEA to connect to this machine. Go to Run –> Edit Configurations… Click on the + icon and add Tomat Server –> Remote configuration. Make sure you specify the host IP address correctly. You can also modify the ‘Open Browser’ option so that the java app launches when you start debugging.

image

Switch to ‘Startup/Connection’ tab and set the TCP port to the one you used while setting up Tomcat, 1043 in this case,

image

Save the debug configuration and set a breakpoint in the doGet() function in MyServlet.java file. Now start debugging. You should see the web browser launch and when you click on the link to invoke the servlet, your breakpoint should be hit.

image

In case you see an error in IDEA which says ‘unable to connect : connection refused’, you might need a firewall exception for incoming connections on port 1043 (and 8080 too). So go to Windows Firewall settings and create an inbound rule on TCP port 1043 to allow incoming connections, and that should fix the problem.

Windows Phone 7: Translation, rotation, scaling and the effect of ‘BitmapCache’ on performance

One thing that was pending on my “todo” list from a long time was implementing the ‘Game Of Life’ on Windows Phone 7. I got the basic version running in a couple of hours and I’ve been thinking about improving it since and adding new features to it. Maybe I’ll submit it to the marketplace someday, who knows. I have also been reading about gestures, multi-touch, pinch-to-zoom and related topics and most importantly trying to understand the math behind each of those gestures, and the math is so elegant that it fascinates me!

Game Of Life
Game Of Life is a simple cellular automaton in which you create a pattern in a world made of rectangular grids, start the evolution process and then watch the pattern change as the world evolves. The world is made up of dead cells initially, you create a pattern by selecting a few cells and giving them “life”. The world then evolves according to a set of rules (source: Wikipedia):

  1. Any live cell with fewer than two live neighbours dies, as if caused by under-population.
  2. Any live cell with two or three live neighbours lives on to the next generation.
  3. Any live cell with more than three live neighbours dies, as if by overcrowding.
  4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

It’s a fascinating concept and some very interesting patterns emerge out of it, read more about Game Of Life on Wikipedia here.

Gestures
Gestures like translation, scaling and rotation seemed complex to me at first, but they’re pretty simple once you understand the math that makes the magic happen. I came across two great articles that really dig deep into these concepts. Both articles use the Silverlight Toolkit for Windows Phone 7 and the gesture support that it provides. I was a little surprised to know that the silverlight toolkit actually uses XNA’s touch api’s to detect gestures. These are the articles that you must read:

MSDN Magazine : Touch Gestures on Windows Phone by Charles Petzold. This is the implementation I chose to use in my app Game Of Life. The code is available for download in the article.

Windows Phone 7: Correct pinch zoom in silverlight by Francesco De Vittori. I was using this before I stumbled on Charles’ article :) Also, Charles’ implementation seemed more intuitive to me.

Charles Petzolds’ implementation makes use of Matrix transforms. It took me some time to understand matrix transforms and realize their importance in 2D/3D graphics. The only time I used matrix multiplication was to solve silly linear equations in college. You’ll find many a articles on the internet about matrix transforms but the best resource I found again comes from Charles Petzold. Chapter 22 – From Gestures to Transforms in his free book Programming Windows Phone 7. Download it now if you haven’t already, it’s a great resource.

The two paths had to meet. Using gestures in Game Of Life was the best way to learn them.

In my first implementation of Game Of Life, I used the Manipulation Delta events to support pinch-to-zoom. In this I used the DeltaManipulation.Scale.X and DeltaManipulation.Scale.Y values in the ManipulationDeltaEventArgs class (passed to the ManipulationDelta event handler) to modify the ScaleX and ScaleY values of a Scale transform on the object to be scaled. If that sentence didn’t make sense, don’t worry, this is the easiest and the worst implementation of pinch-to-zoom. The scaling was not smooth or accurate. To understand what a perfect pinch-to-zoom should be read this – Pinch Zooming using XNA on WP7: Getting it right. The article explains this with reference to XNA but the concept remains the same everywhere.

In my second attempt I used the Silverlight Toolkit for Windows Phone and Francesco’s implementation of pinch-to-zoom. It was working pretty nicely with a few quirks here and there. Though the implementation is easy to understand, I felt there were too many variables used for storing state information and the code looked a bit messy, but it worked.

It is while tuning this implementation that the MSDN Magazine article was published. Charles Petzold’s implementation felt intuitive and was much cleaner. The only part I had to figure out was the matrix transforms he used. And that I’ll explain a bit here.

This is what the app looks like,

game-of-life

The rectangular grids are added programmatically to a canvas. Here is the XAML for the canvas,



    
        
            

            
                
                
                
            

        
    


So during the Drag Delta and Pinch Delta events the transforms under currentTransform are manipulated to achieve the desired effect and once the drag or pinch gestures are completed a function, TransferTransforms(), is called:

void TransferTransforms()
{
    previousTransform.Matrix = Multiply(previousTransform.Matrix, currentTransform.Value);

    //Set current transforms to default values
    scaleTransform.ScaleX = scaleTransform.ScaleY = 1;
    scaleTransform.CenterX = scaleTransform.CenterY = 0;

    rotateTransform.Angle = 0;
    rotateTransform.CenterX = rotateTransform.CenterY = 0;

    translateTransform.X = translateTransform.Y = 0;
}

Matrix Multiply(Matrix A, Matrix B)
{
    return new Matrix(A.M11 * B.M11 + A.M12 * B.M21,
            A.M11 * B.M12 + A.M12 * B.M22,
            A.M21 * B.M11 + A.M22 * B.M21,
            A.M21 * B.M12 + A.M22 * B.M22,
            A.OffsetX * B.M11 + A.OffsetY * B.M21 + B.OffsetX,
            A.OffsetX * B.M12 + A.OffsetY * B.M22 + B.OffsetY);
}

To understand what is happening here we need to look at the XAML first. The RenderTransform on the MainCanvas is a double-barrelled (term used by Charles in his article) transform. Basically, a transform group within a transform group. So the effective transform on MainCanvas is equal to the effect of previousTransform plus the effect of currentTransform. Well, it’s not exactly “plus”. First, previousTransform is applied on MainCanvas to change its state, and then currentTransform is applied on that state to change it further. If you download and look into Charles’ code, you’ll see that during drag delta and pinch delta events, only currentTransform values are modified. Once the drag or pinch gesture is complete, TransferTransform() is called to “transfer” the values of currentTransform to previousTransform. And this transfer happens by the way of matrix multiplication, which is what the function Mulitply() does. It’s not over yet. After the multiplication the values of currentTransform (i.e scaleTransform, rotateTransform and translateTransform) are reset. This is important because, as we discussed before, the effective transform on MainCanvas is effect of previousTransform “plus” the effect of currentTransform. Transferring the values of currentTransform to previousTransform and then resetting currentTransform keeps the effect same.

CacheMode and BitmapCache
Now I got the translation, scaling and rotation to work correctly, but the performance was not very great. There was a huge lag in pinching and dragging, and this is where BitmapCache comes in. Every UIElement has a property called CacheMode, which can be set to BitmapCache.

In XAML, CacheMode=”BitmapCache”

In code, uiElem.CacheMode = new BitmapCache();

When the CacheMode of a UIElement is set to BitmapCache, a snapshot of the UIElement is taken and is stored in the video memory. So the element is not redrawn every time, instead all the operations are performed on the cached bitmap. This is super fast and is particularly useful when working with transforms on controls. Change the MainCanvas element in the XAML to include CacheMode,

 

and this will have a dramatic effect on the performance as you will see in the video below.

Please leave a comment if you have anything else to add.

Until next time..