Extreme Java When vanilla Java is not enough

31Oct/080

Configuring SOAPInput node listener port

If you use IBM's WebSphere Message Broker to expose a webservice using a SOAPInput node, you notice that it listens to the 7800 port by default (or 7801, 7802, if you deploy other message flows, too). If you want to configure that port (changing it to 8080 or any other port number), you need to issue this command:

$ mqsichangeproperties BRKNAME -e default -o HTTPConnector \
                               -n explicitlySetPortNumber -v 8080
BIP8071I: Successful command completion.

After restarting the broker, it will open the desired port.

30Oct/080

BufferedImage and ByteBuffers

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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);

Line 15 leads me to an ugly exception:

java.awt.image.RasterFormatException: IntegerComponentRasters must
haveinteger DataBuffers
  at sun.awt.image.IntegerComponentRaster.
    (IntegerComponentRaster.java:155)
  at sun.awt.image.IntegerInterleavedRaster.
    (IntegerInterleavedRaster.java:111)
  at sun.awt.image.IntegerInterleavedRaster.
    (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...