4 posts tagged “java”
I took up the challenge posted over at Binstock regarding Small Classes and Short Methods and have to say it was an interesting exercise. Overall implementing these suggestions made for much more readable code, and it was certainly more OO after I finished than before.
And indeed it was. It was also one of the more important constraints. From this constraint arose insights into the relationships between elements in the underlying structure. It forced thinking *this much* harder about what is going on, and in the process finding ways to do things that are a bit more OO.7. Don’t use any classes with more than two instance variables. This is perhaps the hardest constraint.
This "50 lines" constraint is the only one that I really felt to be almost impossible to strictly adhere to. If your class overrides Object methods (toString(), equals(), hashCode(), etc.) then you are already eating up some portion of this. I ignored these for purposes of the "lines per class" metric; I don't think the spirit of the exercise suffered.6. Keep entities small. This means no more than 50 lines per class and no more than 10 classes per package.
Current revisions of Eclipse prevent the use of SoyLatte, the OpenJDK port of Java 1.6 for OS X 10.4/10.5. There is an open bug about this, and even better a patch for StandardVMType attached to the bug. I've applied the patch and it does indeed work. There is actually only a single jar used by Eclipse that needs to be built, and most of this can be done within Eclipse itself. The steps for doing this are outlined below.
- Download the Eclipse source. Unzip it.
- From within Eclipse do File | Import... | Existing Projects into Workspace and hit Next. Set your root directory to ${eclipse_src}/plugins/org.eclipse.jdt.launching. Copy the project into the workspace, just to save potential trouble.
- Check out the patch. Copy it to your clipboard.
- To apply the patch go to StandardVMType.java in the Package Explorer, right click, Team | Apply Patch...
- Now to export the plugin, i.e. build the jar needed by Eclipse. Again from within Eclipse: File | Export... | Plug-In Development | Deployable plugs-ins and fragments. Check off the plugin and perhaps change the output directory. Hit finish. You should have the jar with the applied patch in your output directory now.
- Exit Eclipse.
- From your Eclipse home directory (not the source installation, your binary install directory), go to plugins/ and find a file that is named something like org.eclipse.jdt.launching_3.3.1.v20070808_r331.jar. Move this file to a backup directory of your choosing.
- Copy the file generated in step (5) to here.
- Restart Eclipse.
- Go to Eclipse preferences | Java | Installed JREs and try and add SoyLatte as a JRE. If everything worked you should be able to do so without error.
When doing J2EE development against Java5 a frequently encountered warning message is "The cast from X to Y is actually checking against the erased type Y." This is most frequently seen when getting a request or session attribute and putting it into a genericized collection:
List<MyObj> = (List<MyObj>) request.getAttribute(SOME_OBJ);
This constantly annoys me, so I came up with the following and put it in a helper class:
public static Collection<?> getAttributeAsTypedCollection(HttpServletRequest request, String attribute) {
Collection<Object> c = null;
Object obj = request.getAttribute(attribute);
if (null != obj && obj instanceof Collection) {
c = new ArrayList<Object>();
Collection<?> tmpList = (Collection<?>) obj;
c.addAll(tmpList);
}
return c;
}
Calling it with the following produces no warnings:
List<Integer> newList = (ArrayList<Integer>) getAttributeAsTypedCollection(request, "myAttr");
I have recently been experimenting with using Selenium for testing web applications, and have had both positive and negative experiences. Selenium tests run directly in a browser; the browser can be specified at runtime via a constructor argument. For example:
public void setUp() {
sel = new DefaultSelenium("localhost",
4444, "*firefox", "http://url-of-app-being-tested:port");
sel.start();
}
The tests themselves take the form of the following:
public void testLinkNotPresent() {
sel.open("/");
sel.isTextPresent(LINK_TEXT);
}
See the JavaDoc for the DefaultSelenium class for more information on how to build tests.
Now, while this has proven to be a useful tool, my main hesitation revolves around the speed of the tests. If you are using JUnit 3.x -- not uncommon in most Java shops -- each of your test* methods will have a new DefaultSelenium object created. This means that a new browser window will be created for each test. And it's not just that a new browser window is opened, but that they are opened multiple times for each test: apparently the browser is initially loaded to have its proxy settings set so that it will talk to the Selenium server, then closed, then reloaded, then reloaded again for some reason, at which point the tests actually start.
My test class called had only 7 tests total in it, but nonetheless it took some 3 minutes to run.
The Selenium website recommends using TestNG to alleviate this problem with the setUp() method, and apparently JUnit4 also provides a global "setUp" method that only gets called once. Neither of these are suitable options.
The final nail in the coffin was that Safari is not a supported browser.
Final verdict: Selenium is interesting, but still needs work. My next step is to compare it with jWebUnit.
Edit: Ran across this in a JUnit FAQ: How do I run setup code once for all my TestCases? This recommends modifications to your suite class, but if you aren't using suites (I am not) it's not very helpful.