Archive for the ‘Java SE’ Category

That’s extreme!

Wednesday, September 16th, 2009

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

Java Service Provider Interface (SPI)

Thursday, March 19th, 2009

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.

Spring classes and their long names

Monday, March 16th, 2009

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.

Jasper Reports tutorial - part 2 - tables

Monday, March 16th, 2009

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>

Jasper Reports (quick and dirt) tutorial

Thursday, March 12th, 2009

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)

Writing XML with namespaces using DOM

Thursday, February 12th, 2009

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!

One more strange bug

Friday, November 28th, 2008

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

Dynamic code in Java (a.k.a. “eval in Java”)

Thursday, November 6th, 2008

I really don’t like eval-like structures. They are evil. It is a headache to test, makes code ugly, hard to optimize, etc. I simply don’t like them.

But I finally found a use to them. It’s very common to use scripting to create a flexible system. I have a ticket filter that uses Spring and EL to create filtering rules in a “building blocks”-way. It is cool, easy to maintain, but it is not optimized: hundreds of instances in a Composite Pattern (with some expressions) must be navigated to find a simple boolean answer: keep or discard?

Java 6 has a not-so-secret feature that allows invoking the javac using Java code: you pass the files to the framework, it builds compiled classes. You can find how in the JavaCompiler’s API. It mentions an example of a JavaSourceFromString class that you can implement and give the compiler java code stored in String. Very useful!

But, if you try and run a test (like this one), you will receive a nice class file. But that’s not what I want. I want it loaded and ready-to-go. How to interface with this new class when it is loaded? Reflection? Maybe, but I prefer another way: interfaces. I already have this simple one:

package pkg;
public interface Filter {
    boolean filter(VO vo);
}

It is the base of my filter infrastructure. If I change JavaBeat test code to something that “implements pkg.Filter”, my whole problem is solved, with minimal changes on the rest of the code.

Nice! We can interface with the class, but it is not loaded! I could read the class file and pass it to the ClassLoader, but I don’t want to create a file. This class does the trick:

class JavaObjectToByteArray extends SimpleJavaFileObject {
    private ByteArrayOutputStream output = new ByteArrayOutputStream();
    public JavaObjectToByteArray(String className, Kind kind)
            throws URISyntaxException {
        super(new URI(className), kind);
    }
    @Override
    public OutputStream openOutputStream() throws IOException {
        return output;
    }
}

You can pass this object by overriding ForwardingJavaFileManager.getJavaFileForOutput:

fileManager = new ForwardingJavaFileManager(fileManager) {
  @Override
  public JavaFileObject getJavaFileForOutput(Location location,
      String clazz, Kind kind, FileObject sibling) throws IOException {
    try {
      JavaObjectToByteArray jfo = new JavaObjectToByteArray(clazz, kind);
      cl = new ByteArrayClassLoader(className, jfo.output);
      return jfo;
    } catch (Exception ex) {
      throw new IOException(ex);
    }
  }
};

ByteArrayClassLoader is:

class ByteArrayClassLoader extends ClassLoader {
  private String clazz;
  private ByteArrayOutputStream baos;
  public ByteArrayClassLoader(String clazz, ByteArrayOutputStream baos) {
    this.baos = baos;
    this.className = className;
  }
  @Override
  protected Class<?> findClass(String name) throws ClassNotFoundException {
    byte[] data = baos.toByteArray();
    return defineClass(name, data, 0, data.length);
  }
  public Class<?> loadClass() throws ClassNotFoundException {
    return loadClass(className);
  }
}

The “loadClass” method is a convenience method, since this class loader only loads one class. With one line of code, I can use my brand-new-dynamic-class:

Class<?> clz = cl.loadClass();
Filter f = (Filter) clz.newInstance();
System.out.println(f.filter(vo));

BTW, there’s only one small change in JavaBeat’s code. I need a “public” class, and this means the java file must be named “MyClass.java” (not “MyClass”). You only need to change JavaObjectFromString constructor from:

super(new URI(className), Kind.SOURCE);

to:

super(new URI(className + ".java"), Kind.SOURCE);

Easy, huh? It is not like “eval” in JavaScript, but it is better, since this class will be JIT’ed.

BufferedImage and ByteBuffers

Thursday, October 30th, 2008

Direct ByteBuffer are really cool, because they can allocate and wrap native memory outside the JVM heap. This is very useful with JNI or with large files. I’m playing with OpenGL and PCX files (this is evil, I know). Since I want to keep a small footprint, I want to keep only a pointer to PCX raw data (run-lenght encoded), and decompress it into a RGBA ByteBuffer as needed. This, in theory, allows me to share the same code with OpenGL and BufferedImage - since I’m bound only to a pointer of RGBA data. The former is easy: TextureData did the dirt job. The latter… Well… Not that easy. If you try something like this:

final IntBuffer buf = myPCXLoader.getImage();
DataBuffer dataBuffer = new DataBuffer(
    DataBuffer.TYPE_INT, buf.limit()) {
  @Override
  public int getElem(int bank, int i) {
    return buf.get(i);
  }
  @Override
  public void setElem(int bank, int i, int val) {
  }
};
SampleModel sm = new SinglePixelPackedSampleModel(
    DataBuffer.TYPE_INT, w, h,
    new int[] { 0xFF000000, 0xFF0000, 0xFF00, 0xFF });
WritableRaster raster = Raster.createWritableRaster(
    sm, dataBuffer, null);
BufferedImage img = new BufferedImage(
    new DirectColorModel(32, 0xFF000000, 0xFF0000, 0xFF00, 0xFF),
    raster, false, null);

The red line leads me to an ugly exception:

java.awt.image.RasterFormatException: IntegerComponentRasters must
haveinteger DataBuffers
  at sun.awt.image.IntegerComponentRaster.<init>
    (IntegerComponentRaster.java:155)
  at sun.awt.image.IntegerInterleavedRaster.<init>
    (IntegerInterleavedRaster.java:111)
  at sun.awt.image.IntegerInterleavedRaster.<init>
    (IntegerInterleavedRaster.java:78)
  at java.awt.image.Raster.createWritableRaster(Raster.java:994)

Asking Google, I found that ByteComponentRaster checks if DataBuffer is a instanceof ByteDataBuffer (instead of checking its type). Disgusting… Looks like Sun hired some kind of Baby Junior Programmer taking his first cup of Java to make that part of java.awt…

I also found this 3-years-old-and-not-solved-yet bug, with an workaround:

WritableRaster raster = new WritableRaster(sm, dataBuffer,
    new java.awt.Point()) {};

Works like a charm!

Sun is really disappointing me. There are a lot of small, simple-to-solve, really old bugs and seems like nobody cares about them. I think this is why they are opening the source of their major products: let the community clean the mess…

IOException when loading a sound/midi from a JAR/ZIP archive

Thursday, August 28th, 2008

I have a MIDI file in a JAR archive. If I try to play it with the Sequencer class, I got an exception: “java.io.IOException: mark/reset not supported”. I’ve found this related bug. I don’t like workarounds (all bugs must die), but I developed this one:

public static InputStream loadStream(InputStream in) throws IOException {
  ByteArrayOutputStream bos = new ByteArrayOutputStream();
  byte[] buf = new byte[1024];
  int c;
  while ((c = in.read(buf)) != -1) {
    bos.write(buf, 0, c);
  }
  return new ByteArrayInputStream(bos.toByteArray());
}

With this method, I encapsulate the “unresetable” stream into a “resetable” ByteArrayInputStream.