Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Monday, March 14, 2011

NavigableMap in JDK6

JDK6 introduced NavigableMap and retro-fitted TreeMap to implement this interface. I was a bit confused at first about ceilingKey vs higherKey and floorKey vs lowerKey. It turns out that floor and ceiling operations can return equal entries, while higher and lower operations must be strictly less than or greater than.


Nice features. I can definitely find some uses for them. :)

Tuesday, November 23, 2010

Use compiler to catch new enum value not covered in "switch"

This old trick shines more and more when our project's code base grew over million+ lines. I have to put it on the web one more time just in case there is a developer out there haven't seen this.

Basically you can set the compiler to generate compilation errors when there are enum values not covered in switch block. So that when a new value is added to an enum class, every switch statement on this enum class will get a compilation error. This way it is easier to find and add corresponding cases, and it is impossible to ignore them. :)

To make this work, you have to do (or not do) two things:

  1. DO NOT use "default" case when you do switch on enum values.
  2. Set your compiler to generate ERROR instead of ignore enum values not covered in switch. In eclipse (the greatest IDE), it is here:

Tuesday, June 03, 2008

upgrade JBoss Tools from 2.0.1 to 2.1.0

Since JBoss Tools is a drop in plugin, you just copy the files into eclipse/plugin folder to install, I wasn't able to figure out how to remove the old version. It may not matter to eclipse but it just doesn't feel right to have multiple versions hang around. I know you can switch back and forth among different versions. But how often do you switch back? Plus eclipse is not able to recognize 2.1.0 of JBoss Tools anyways.

After fiddling with eclipse plugin management UI for a bit, I lost my patient and went with the brutal force:


cd eclipse/plugin
ls -d org.jboss.tools.* | grep 2.0.1.GA | xargs rm -rf
So far so good. Everything is still working.

Please comment if you have a better way to upgrade JBoss Tools.

Thursday, March 20, 2008

Using SEAM i18n support to externalize strings

SEAM brings support of i18n in JSF applications to a whole new level. It is another show case of "convention over configuration" design philosophy. But its documentation misled me a little bit.

By default, the resource bundle used by Seam is named messages and so you'll need to define your labels in files named messages.properties, messages_en.properties, messages_en_AU.properties, etc. These files usually belong in the WEB-INF/classes directory.
By reading this paragraph, I thought that when all you want is to externalize some labels/strings in your application, you can just throw a file named messages.properties then start referencing resources using messages built-in component. It didn't work like that.
I also tried to force loading the resource bundle using tag core:resource-loader in components.xml file. It didn't work either.
Finally it turned out that you got to put the locale string in your file name although you don't care about locale at all. In my case I just renamed my file as messages_en.properties and everything worked.
I guess it makes sense in a way that a resource bundle got be associated with a locale. But won't it be nice to dump everything without an explicit locale into the default?

Wednesday, September 19, 2007

Saving datetime into database, what timezone is it in?

Moments ago I posted a review on Amazon.com and returned to the product's page, it shows the review was posted 7 hours ago. It seems like Amazon is having a timezone conversion issue.

I am not trying to pick on Amazon. The funny part is that right this afternoon I was asked by a coworker about what timezone a datetime column of our database table is in. Then we had a discussion about how to handle timezones.

Timezone in databases is a delicate issue, and a tricky one to fully understand. Conversion is one issue. Others issues include moving data between database servers running in different timezones, moving data between different database dialects, interpret archived data, etc.

In the past I tried a couple approaches besides blindly saving the Date object through JDBC regardless of the timezone information. In one application I converted the datetime property into UTC time before saving it. In another application I converted time into milliseconds and saved it into database as long number.

I don't have a clear understanding of the relationship among the JVM's timezone, the Date object's timezone, the database server's timezone, the Timestamp's timezone in JDBC result set, and the Datetime column's timezone is MS SQL Studio's result set.

I have the full intension to study this topic in depth and report back.

Stay tuned.

Tuesday, September 18, 2007

the sneaky OutOfMemoryError: PermGen space error

Today I ran into several VERY nice posts which talk about the PermGen errors.

Here are Frank Kieviet's two blogs: classloader leakers and how to fix it (more like how to find it, fixing is likely to be the easy part).

Here is an excellent list of known offenders and links from Spring forum. link.

I cannot wait to modify jhat to map out the heap of my applications. We actually have two applications that are suffering from PermGen errors. One interesting point is that both applications suffer this error when they are hot deployed (unload then load while the application server is running) and when they run for a prolonged period of time. It seems like the first scenario is well examined. It will be very interesting to see what I can find out on the second scenario.

Monday, May 21, 2007

Eclipse setup for blackberry development

These are proven-to-work steps to setup your eclipse environment for developing Blackberry applications. I hope this post will make somebody's entry into the RIM development easier.

To get started, do the following if you haven't done so:

  1. Download and install Eclipse
  2. Download and install BlackBerry JDE
  3. Download and install Apache ant
  4. Download RAPC ant task jar file
Now let's setup our eclipse environment.
  1. Start your eclipse, switch to a brand-new workspace, for example: c:\RIM\workspace
  2. go to Window --> Preferences --> Java --> Installed JREs, click on "Add" button.
  3. In the dialog, leave the default "Standard VM" option for JRE type;
  4. Type in a "JRE name" as you like, such as 'RIM JRE';
  5. In "JRE Home Directory", navigate to your installed JDK home, such as 'C:\Program Files\Java\jdk1.6.0';
  6. Leave "Default VM Arguments" blank;
  7. Now select all the jar files in "JRE System Libraries", then click "Remove" button to remove all of them; Click "Add External JARs", navigate to you Blackberry JDE installation folder, select lib/net_rim_api.jar, such as 'C:\Program Files\Research In Motion\BlackBerry JDE 4.2.1\lib\net_rim_api.jar'.
  8. Click "OK" button to add the new JRE.
  9. Check the checkbox of your newly added JRE to make it the default (Optional: select this JRE, click on "Edit" button to see if the system libraries are still like you set. It happened to me a couple times that eclipse added the jars in JRE home back into the list.)
With the eclipse setup, we are ready to create our first project:
  1. Goto File --> New --> Project, select "Java Project", enter Project Name "HelloWorld", Make sure in the JRE group the "RIM JRE" is selected. In the "Project Layout" group, I prefer to have src and class output into separate folders. Click "Finish" button.
  2. Right click the project, select New --> Folder, create a folder named "lib"
  3. Right click the project, select New --> Folder, create a folder named "resources"
  4. Right click "lib" folder, select "import"; in the dialog, select "general" --> "file system", import the anttask-rapc-1.?.jar you downloaded. Right click the jar file and select "Build Path" --> "Add to Build Path".
  5. Follow the same step to import an icon file in GIF format into "resources" folder. (other image formats work too, we use GIF for demo).
  6. Create a package named "com.mycompany.sample"
  7. Create a class named "HelloWorld.java" in this package and paste these code:
    package com.mycompany.sample;

    import net.rim.device.api.ui.UiApplication;
    import net.rim.device.api.ui.component.LabelField;
    import net.rim.device.api.ui.container.MainScreen;

    public final class HelloWorld extends UiApplication {

    public HelloWorld(){
    super();
    MainScreen screen = new MainScreen();
    screen.add(new LabelField("Hello world!"));
    pushScreen(screen);
    }
    public static void main(String[] args) {
    new HelloWorld().enterEventDispatcher();
    }
    }
  8. Now right click on the project name and create a new file named "build.xml", copy and paste the following code and edit the JRE and RIM JDK pathes accordingly, also search and replace the simulator batch file "8800.bat" to one that exists in your JDE (this ant build script is modified based on a post in Blackberry Java Forum.)

    <?xml version="1.0" encoding="UTF-8"?>

    <project name="HelloWorld" default="buildRIM" basedir=".">

    <taskdef name="rim" classname="com.etaras.anttask.rapc.RAPC" classpath="lib/anttask-rapc-1.8.jar" />

    <property name="jdehome" value="C:\Program Files\Research In Motion\BlackBerry JDE 4.2.1" />
    <property name="javahome" value="C:\Program Files\Java\jdk1.5.0_11"></property>
    <property name="simulator" value="${jdehome}\simulator" />
    <property name="bin" value="${jdehome}\bin" />

    <target name="debug" depends="buildRIM">
    <copy todir="${simulator}" overwrite="true">
    <fileset dir=".">
    <include name="*.cod" />
    <include name="*.debug" />
    <include name="*.csl" />
    <include name="*.cso" />
    </fileset>
    </copy>
    <exec executable="cmd.exe" dir="${bin}" spawn="true">
    <arg value="/c" />
    <arg value="jdwp.bat" />
    </exec>
    </target>

    <target name="simulate" depends="deploy">
    <exec executable="cmd.exe" dir="${simulator}" spawn="true">
    <arg value="/c" />
    <arg value="8800.bat" />
    </exec>
    </target>

    <target name="deploy" depends="buildRIM">
    <copy todir="${simulator}" overwrite="true">
    <fileset dir=".">
    <include name="*.cod" />
    <include name="*.debug" />
    <include name="*.csl" />
    <include name="*.cso" />
    </fileset>
    </copy>
    </target>

    <target name="buildRIM" description="Composes RIM">
    <rim jdehome="${jdehome}" javahome="${javahome}">
    <workspace src="helloworld.jdw" build="true" update="true">
    <cldc src="helloworld.jdp"
    title="HelloWorld"
    vendor="my company"
    version="0.1"
    description="HelloWorld"
    arguments=""
    systemmodule="false"
    runonstartup="false"
    startuptier="7"
    ribbonposition="0"
    output="helloworld"
    options="-quiet"
    update="true">
    <files dir=".">
    <include name="**/*.java" />
    <include name="resources/**/*.*" />
    </files>
    <icons dir=".">
    <include name="resources/**/*.png" />
    <include name="resources/**/*.gif" />
    </icons>
    </cldc>
    </workspace>
    </rim>
    </target>

    </project>

  9. Open a DOS window, change to the directory where you have your build.xml file, type "ant simulate", this task will build the project, deploy it and start the simulator.
  10. Look for the logo you picked for your HelloWorld app and open it, you should see a blank screen displaying "Hello World!". How exciting!
I will write down my experience of debugging applications inside eclipse in the next couple of days.

Thursday, May 03, 2007

Downgrade default JRE on windows XP

When installing Blackberry signature keys yesterday, I need to downgrade my default JRE on windows XP from 1.6 to 1.5. (Java is so good at maintaining backward compatibility, I seriously want to figure out what made the installation process not working in Java1.6. If you have a clue, please comment. Thanks.)

The complexity of this process caught me off guard. As a linux user, I instinctively went to My Computer --> Properties --> Advanced --> Environment Variables, and set the pathes. It doesn't work this way though. (Gentoo users, enjoy your java-config util and laught at me)

After some digging, here are the steps worked for me.

  1. Copy java.exe, java2.exe, javaws.exe from C:\Program Files\Java\jdk1.5.0_??\bin to C:\WINDOWS\system32\ to overwrite existing 1.6 version files.
  2. Open registry editor, goto Start --> Run, type in "regedit" and enter.
  3. Do a search for "JavaSoft", you should find something under HKEY_LOCAL_MACHINE -->SOFTWARE --> JavaSoft --> Java Runtime Environment, modify "CurrentVersion" key to "1.5" or the version you want.
  4. Update the correspondent environment variables.

Tuesday, October 31, 2006

When doing JasperReports yesterday, I encoutered a weird problem. I have some text fields that holds long strings, so the text has to be wrapped. So I set the text fields to stretch with overflow. It worked fine in iReports 1.2.6. But after deploying it to a web application (Centric CRM), some text fields got the last line cut off, just the last line. And this is not happening on all fields in a page, just some.

I tried different versions of JasperReports and Lowagie iText libraries without any luck. Eventually I figured it out. I have the text fields height set to 18 pixels and my detail band set to 20 pixels so I can get a little padding on top and bottom. Somehow these little padding confused JasperReports. After setting all textfields and band to 20 pixels height, everything worked fine. To archieve the little padding, I set the padding in the Border tab in Properties dialog.

Long story short: When doing JasperReports, if you get the last line cut off when setting Textfield to stretch with overflow, check the text field height and band height. It may help.