Extreme Java When vanilla Java is not enough

6Apr/110

Differences between ArrayList and Vector

Last friday, I posted the differences between HashMap and Hashtable. Studying a little more, I decided to checkout the differences between ArrayList and Vector. Surprise! The same three items, plus one bonus:

  1. Vector is thread-safe, ArrayList isn't;
  2. ArrayList supports null items;
  3. Vector's enumerations are not fail-fast; and
  4. You can pass the capacity increment to Vector's constructor.
Filed under: Java SE No Comments
3Apr/110

SwingWorker from JavaSE 6

So, you didn't know about SwingWorker? Neither do I, but it is a very nice addition from JavaSE 6. You can use it as a background thread (instead of Thread class) when your task needs to communicate with Swing.

SwingWorker is abstract and needs you to implement a method "doInBackground" that is the equivalent of "Thread.run". So far, no changes. First difference is that SwingWorker implements "Future", this means it will return the result of processing. Second one is you can override methods like "done" and "process", to work with the result in EDT after the task finishes and partial results, respectively.

SwingWorkers can be cancelled with "cancel(boolean)". This changes a "cancelled" flag that can be checked with "isCancelled". BTW, if the parameter is "true", an old-school "interruption" will also be made on the task.

In "doInBackground", you can also call "progress" (running in worker thread) to report partial results to "process" (in EDT).

SwingWorker has bound properties, specially "progress" (int ranging from 1 to 100, perfect for JProgressBar), and "state" (PENDING, STARTED, DONE), and two type parameters: first for the return type, second for the partial result type (if any).

I need to invest some time in my old projects (like GEBORA) to use this incredible leverage.

BTW, if you need a thread pool, pass SwingWorker to an Executor.

Filed under: Java SE No Comments
1Apr/110

Differences between HashMap and Hashtable

Fun facts about HashMap and Hashtable:

  1. Hashtable is thread-safe, HashMap isn't - that's something everybody knows;
  2. HashMap supports null keys and values - not so obvious, but very important;
  3. Enumerators returned from an Hashtable aren't fail-fast. Iterators from both classes are.

That was one of many questions I had to answer in a job interview. I admit I couldn't remember the second and third ones. I think I must study to upgrade my SCJP certification to refresh this kind of detail.

Filed under: Java SE No Comments
16Sep/090

That's extreme!

And, talking about being extreme, I found a mix of bytecode programming with ASCII art...

Filed under: Java SE No Comments
19Mar/090

Java Service Provider Interface (SPI)

Long time ago, I had a bad time trying to develop a "plugin mechanism" to my "open source Toad". What I didn't know is how to use the service provider infrastructure avaliable since Java 1.3 (what a shame!).

If you want to create a service provider interface (SPI):

  1. Define an interface or abstract class (this will be implemented/overrided by the provider)
  2. Use "ServiceLoader.load" when you need the concrete instances (it's an iterator that can be used in a "foreach")

If you want to provide a service (the plugin itself):

  1. Implement/override the code of SPI
  2. Create a META-INF/services folder
  3. Create a file with the same name of the SPI class and add the name of the concrete classes from step 1

And we are done! A simple, yet robust, solution to add extensibility.

Tagged as: , No Comments
16Mar/090

Spring classes and their long names

Spring team likes big names. One of the biggest is "SimpleRemoteStatelessSessionProxyFactoryBean". This is not a problem, since I'm not a Fortran programmer. Unfortunatelly, I found two classes with similar names that aren't type-safe (i.e.: I don't receive a ClassCast or similar if I swap them): MethodInvokingFactoryBean e MethodInvokingJobDetailFactoryBean. I use the latter a lot, but, after using NB's autocomplete feature, I selected the former instead:

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
  <property name="targetObject" ref="cache"/>
  <property name="targetMethod" value="reload"/>
</bean>

Results? NullPointerException:

org.quartz.SchedulerException: Registration of jobs and triggers failed: null [See nested exception: java.lang.NullPointerException]
  at org.springframework.scheduling.quartz.SchedulerFactoryBean.registerJobsAndTriggers(SchedulerFactoryBean.java:861)
  at org.springframework.scheduling.quartz.SchedulerFactoryBean.afterPropertiesSet(SchedulerFactoryBean.java:649)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1368)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1334)
  ... 13 more
Caused by: java.lang.NullPointerException
  at org.quartz.core.QuartzScheduler.addJob(QuartzScheduler.java:808)
  at org.quartz.impl.StdScheduler.addJob(StdScheduler.java:288)
  at org.springframework.scheduling.quartz.SchedulerFactoryBean.addJobToScheduler(SchedulerFactoryBean.java:883)
  at org.springframework.scheduling.quartz.SchedulerFactoryBean.addTriggerToScheduler(SchedulerFactoryBean.java:906)
  at org.springframework.scheduling.quartz.SchedulerFactoryBean.registerJobsAndTriggers(SchedulerFactoryBean.java:842)
  ... 16 more

This wasn’t easy to solve, since the NPE wasn’t obvious. Both MIFB and MIJDFB are “factory” instances (they create real instances as needed), and, in this case, no type check was done.

16Mar/090

Jasper Reports tutorial – part 2 – tables

I never planned a "part 2" about Jasper Reports, but the previous "tutorial" lacks a small concept: how do I make tables? It's obvious, but only after you figure it out. If you downloaded Jasper Reports examples, you can look at "datasource" sample. Nice one, but not as simple as you may want.

I only want to add a basic table which row data comes from a Java Collection. It is very easy to adapt the JasperFiller: just change JREmptyDatasource with JRBeanCollectionDataSource.

Adapting JRXML is easy, too, but it not obvious for a newbie. I admit I expected something like a "table" element (blame years of HTML), but in JR, you only need to define the "detail" element with the contents you want to repeat for each element on DataSource. Create it as you want, tune the band height to the height of a row, and you have your HTML-ish table.

BTW, you need to define all fields at the top of your JRXML, since JR's DataSources does not contains metadata.

As a last tip, keep these in mind:

  • <title> only appears on first page;
  • <pageHeader> and <pageFooter> appears on every page;
  • <lastPageFooter> apperars only on last page, REPLACING <pageFooter>
12Mar/090

Jasper Reports (quick and dirt) tutorial

If you want a simple Jasper Reports tutorial, you will have a bad time googling it. The official site has a nice theorical introduction, but after reading it, you will not have a working "hello world" example. Unfortunatelly, the "definitive guide" is a book you need to buy.

Since I prefer a "try-before-you-buy" approach, I asked Google and I've found a simple "hello world" JRXML reading this tutorial from David Heffelfinger's article. Good one, but I will upgrade it. The XML can use XSD:

<?xml version="1.0" encoding="UTF-8"?>
<jasperReport name="report name"
  xmlns="http://jasperreports.sourceforge.net/jasperreports"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports
    http://jasperreports.sourceforge.net/xsd/jasperreport.xsd">
  <detail>
    ...
  </detail>
</jasperReport>

If you are using NetBeans 6, go to "Tools > Options > Miscellaneous > Files", add "jrxml" extension and associate with "application/xml". Now, it will autocomplete jasper tags for you. You can use iReport NB plugin, too, but I like to know how it work.

Well, you need to compile this JRXML before using it. David shows how to do programmatically. If you want to add only the compiled version to your JAR file, you can add this to your Ant build file (this is a NB version, change parameters as needed):

<target name="-post-init">
  <!-- Init jasper ant task -->
  <taskdef classpath="${javac.classpath}"
      classname="net.sf.jasperreports.ant.JRAntCompileTask"
      name="jrc" />
</target>
<target name="-post-compile">
  <!-- without a tempdir, JR may
       create files on NB folder! -->
  <mkdir dir="${build.dir}/jasper"/>
  <!-- compile "src/JRXML" to "build/JASPER" -->
  <jrc destdir="${build.classes.dir}"
       tempdir="${build.dir}/jasper">
    <src>
      <fileset dir="${src.dir}" includes="**/*.jrxml" />
    </src>
    <classpath>
      <path path="${javac.classpath}"/>
    </classpath>
  </jrc>
</target>

Now you have a ".jasper" file on your build dir, together with your compiled classes - just ready for use! Let's use it:

InputStream in = getClass().getResourceAsStream("/my-pkg/myReport.jasper");
JasperPrint jasperPrint = JasperFillManager.fillReport(in,
        new HashMap(), new JREmptyDataSource());
JasperExportManager.exportReportToHtmlFile(jasperPrint,
        "output-path/report.html");

Pretty easy, huh? One last note - you will need more libs than just "jasperreports.jar" on your classpath:

  • commons-digester
  • commons-logging
  • commons-collections
  • commons-beanutils
  • itext (only if you want to export as PDF)
12Feb/090

Writing XML with namespaces using DOM

Java has a lot of ways to interact with XML files: JAXB, SAX, DOM... I don't have a favorite one: each one has its own pros and cons. SAX is great to parse adhoc, JAXB is better when you can map your XML into a POJO tree, and DOM is the choice when your XML is well-formed, but can't be easily mapped into POJO.

I'm playing with JSPX files (JSP using XML syntax), and I got an idea: "why can't I build an JSPX using DOM"? Gene Davis has a great tutorial about creating an XML using DOM. No external library needed (like JDOM). It is almost perfect, but, if I want to create a JSPX, I will use a lot of namespaces. DOM specification level 2 doesn't support namespaces directly, but you can use dirt tricks to get this. Based on Gene's example, you only need to change the root element:

Element root = doc.createElement("jsp:root");
root.setAttribute("xmlns:jsp", "http://jsp");
root.setAttribute("xmlns:f", "http://faces");
doc.appendChild(root);

The trick is to consider the namespace declarations as attributes (since this is what they are). The result XML becames:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<jsp:root xmlns:jsp="http://jsp" xmlns:f="http://faces">
    <!--Just a thought-->
    <jsp:child name="value">Filler, ... I could have had a foo!</jsp:child>
</jsp:root>

BTW, I changed the child to "jsp:child" (without the xmlns attributes), removed the "OMIT_XML_DECLARATION" output property, and, to indent correctly, I added this property:

trans.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

Apache attribute on Sun's RI... Yikes!

Tagged as: , , No Comments
28Nov/080

One more strange bug

I've noticed that all Java applications on my machine are slowing down a lot. But, when I my brand-new and self-made budget application freezes while doing a "new JFileChooser()", this really pi**es me off. Asking Google, I found another weird bug: when your Windows Desktop has a lot of ZIP files, Java will implicity use Windows "zip folder" feature.

You can also blame Microsoft, because Win32ShellFolder.isDirectory() returns "true" (in W32API terms) when checking zip files. Don't you love proprietary API?

Workarounds:

  1. Clean your Desktop
  2. If you are as lazy as me, you can disable "zip folder" with:
    regsvr32 /u %windir%\system32\zipfldr.dll