Social Icons

twitterfacebookgoogle pluslinkedinrss feedemail

Thursday, July 5, 2012

Running Again

Two months out of surgery on my right knee and I'm up to 3/4 mile. Granted, it's at a 12:00 pace, but who cares? I'm running again and it's pain free.

After surgery on my right knee last October and before I started running again, I had an MRI done on my left knee to make sure I wouldn't make things worse by ramping up my running again. As it turned out, I had the exact same tear in my medial meniscus in my left knee that I had in my right. It wasn't as bad and the flap that had torn did not fold over on itself - which is why I never had any left knee pain - but there was some VERY minor damage in my lateral meniscus. So, when they went in for surgery they fixed both.

I was originally going to wait until this fall to have surgery on my left knee, but there really was no reason to wait any longer and it was keeping me from running so I went ahead and had it done.

Thursday, April 26, 2012

Java Generics and Type Erasure

I recently came across a situation at work where knowing the generic type on a field was needed and it turns out that my initial understanding of Java Generics was not correct. Java Generics provide compile-time type safety and my understanding was that these types were erased after compilation and were not accessible at run-time. It turns out, this only true at the class level but generics are not erased for fields and methods.

Here's an example, first, let's define a simple class:

import java.util.List;

public class GenericsTest {

  public GenericsTest() {
    this.stringList = null;
    this.stringField = null;
  }

  private List<String> stringList;
  private String stringField;
}

And now for our test:

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class FieldGenericsTest {

  public static void main(String[] args) throws Exception {

    GenericsTest gt = new GenericsTest();

    Field[] fields = gt.getClass().getDeclaredFields();
    for (Field field : fields) {

      // needed to access non-public fields
      field.setAccessible(true);

      Type fieldType = field.getType(); // will be List without generics
      System.out.println("field type: " + fieldType);

      Type genericType = field.getGenericType();
      if (genericType instanceof ParameterizedType) {

        ParameterizedType pt = (ParameterizedType) genericType;
        Type[] types = pt.getActualTypeArguments();

        // since we only have one generic type in our example, that is,
        // List<String> contains only one generic type parameter, the
        // size of this array will only be one.
        Type type = types[0];
        if (type.equals(String.class)) {
          System.out.println("generic type is string: " + type);
        }
      }
      else {

        // fields without generics will fall here
        System.out.println("not a parameterized type: " + genericType);
      }
    }
  }
}

This, by itself, is pretty powerful for the use cases where the generic type needs to be known at run-time. But, what if you have multiple fields with the same type/generic signature? That is, we have two fields with the type List<String>. We can use annotations to distinguish these fields apart and then access the annotations while we're iterating over the fields. My next post will deal with that use case.

Tuesday, January 17, 2012

Referencing third-party library source code in a GWT project.


It turns out the process is slightly involved - especially when Maven is added to the mix.  I don't know if this is the blessed way of solving this issue, but it works.

The first thing I had to do was modify the third-party library POM so that it builds the source jars. This can easily be done by adding the following plugin:


  <plugin>
    <artifactId>maven-source-plugin</artifactId>
    <groupId>org.apache.maven.plugins</groupId>
    <version>2.1.2</version>
    <executions>
      <execution>
        <id>attach-sources-jar</id>
        <phase>verify</phase>
        <goals>
          <goal>jar-no-fork</goal>
        </goals>
      </execution>
    </executions>
  </plugin>


Then, I had to run a build/install of the third-party library to install the sources in my local repo.

Next, I needed to modify the gwt-maven-plugin in my project's POM to tell it to compile the sources for my third-party library. For this, I needed the groupId and artifactId of the third-party library. I had already added this as a dependency in my project's POM and was simply able get the information from there. I then had to modify gwt-maven-plugin plugin's configuration element (in the execution element) to add the compileSourcesArtifacts element as follows:


  <compileSourcesArtifacts>
    <compileSourcesArtifact>groupId:artifactId</compileSourcesArtifact>
  <compileSourcesArtifacts>


Where the text "groupId:artifactId" are the actual groupId and artifactId of my third-party library - don't forget the colon character!

Next, I had to note the package name in the third-party library where the objects I wanted to use were located. For this example, let's assume that this package is "com.foo.bar.bat".

I added a package to my GWT project called "com.foo.bar" leaving out the final "sub-package" of "bat." In this package, I created a new gwt.xml (e.g. Foo.gwt.xml) file and used the artifactId as the name capitalizing the first letter (I don't know if this is necessary but it seems convention in GWT). I then populated this file with the following:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
  "-//Google Inc.//DTD Google Web Toolkit 1.6.4//EN"
  "http://google-web-toolkit.googlecode.com/svn/tags/2.4.0/distro-source/core/src/gwt-module.dtd">
<module>
  <source path="bat"/>
</module>


Note that the value of the "path" attribute is the final "sub-package" I left out above. Additionally, this tells GWT to try and generate JavaScript for ALL the classes in the "bat" package. If there are classes that you want to be ignored, change the <source> element to a block-level element and add a child element called <exclude> that has one attribute called "name" that contains the name of the Java file to ignore, e.g., "Bar.java".

Finally, I added a module inherit dependency to my project's gwt.xml file: <inherits name="com.foo.bar.Foo"/>.  Note that I used the capitalized name of the artifactId as the module.