středa 20. ledna 2010

Eclipse: An error occurred while collecting items to be installed

I have tried to update my Eclipse 3.5 Galileo plugins, and all what I have seen was:
An error occurred while collecting items to be installed
No repository found containing: org.eclipse.net4j.jms.api/osgi.bundle/1.0.0.v200806180305
I could not find the solution for a couple of hours. Finally, BINGO!, reinstalling EclipseLink packages solved it.

Just go to Help -> Install New Software ->, choose Galile update site Galileo - http://download.eclipse.org/releases/galileo and search for all installed EclipseLink packages. (You must uncheck Hide items that are already installed also.) The installed packages have grey icon. Just check them, press Next, and then Finish. Restart the Eclipse and then try to update plugins again.

pátek 16. října 2009

Eclipse: Java Decompiler - Really Nice Plugin

Why the method throws an exception? What happens when I pass a null parameter? Hot the hell is the class designed? These question I have often asked when I had was working with a library without sources. But now I have found a really nice Eclipse plugin http://java.decompiler.free.fr/jd-eclipse/. The update site is http://java.decompiler.free.fr/jd-eclipse/update.

Now I may press F3 button and see the decompiled source immediately. I just miss a possibility to debug the code without source.

středa 16. září 2009

Linux: How to Convert Binary File into Byte Array

Sometimes, a programmer needs to embed a content of a binary file into a program, usually as an array of bytes. For instance, I needed to embed an icon into a Java code, to be really sure the icon is always available for the program. So I have saved an icon in a GIF format and then used the od command. But the result was an unusable list of octal numbers. After a minute with playing, I have found a feasible solution
od -A n -v -t d1 image.gif | sed -e 's/^ *//g' -e 's/  */,/g' -e 's/$/,/g'
I have copied a result into my Java code as
private static final byte[] MISSING_ICON_BYTES = new byte[] { /* copy result here */ };
public static final ImageIcon MISSING_ICON = new ImageIcon(MISSING_ICON_BYTES);

úterý 15. září 2009

Ant: Removing a File from ZIP or JAR

I was facing a common problem with building a Java project by Ant: how to remove one file, and how to replace another file in a JAR (or ZIP) file. Many folks on the web, e.g. here and here, advice to unzip the JAR, delete and replace what's needed, and then create JAR again. But I have found out a simpler solution using a <zipfileset> resource pattern:
<delete file="new.jar">
<zip file="new.jar">
  <zipfileset src="old.jar">
    <exclude name="META-INF/replace.properties"/>
    <exclude name="META-INF/remove.properties"/>
  </zipfileset>
  <zipfileset file="file-to-replace.properties" fullpath="source-file-to-be-replaced.properties"/>
</zip>
You can use any of Ant resources. I personally like zipfileset, because it allows to specify the fullpath attribute, which is the simple way how to change a name of a source file. The <exclude> element is like "delete file" command in this example.

The Ant jar task can be used instead of the zip task, too. But then it has to be specified the META-INF/MANIFEST.MF also, otherwise the jar task creates a new one.

The zip task has one unpleasant "feature". It does not create the file new.jar, if it is newer (has greater timestamp) than the file old.jar. So, I recommend to delete the new.jar file first.

čtvrtek 27. srpna 2009

Java Swing: Flexible Message Dialog

JOptionPane makes life of a developer much easier when one need to show simple message or input dialogs. However, when a huge String or a String with many line breaks is passed to it's showMessageDialog() method, then the message dialog may the screen. For the user, it's better, when the very large messages are wrapped in an JScrollPane. It is possible to pass JScrollPane as an message parameter into to JOptionPane, so far so good. Unfotunatelly, it's not possible to limit the maximum size of the dialog. Finally, I have finished with this solution:
JTextArea textArea = new JTextArea();
textArea.setEditable(false);
// better to keep it true, so the user is able to copy the message to the clipboard
//textArea.setFocusable(false);
textArea.setOpaque(false);
textArea.setText(message);
textArea.setCaretPosition(0); // jump to the beginning
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setBorder(null); // no border, please
Dimension scrollPaneSize = scrollPane.getPreferredSize();
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
scrollPaneSize.width = Math.min(scrollPaneSize.width, Math.max(screen.width / 2, 260));
scrollPaneSize.height = Math.min(scrollPaneSize.height, Math.max(screen.height / 2, 125));
scrollPane.setPreferredSize(scrollPaneSize);
JOptionPane jOptionPane = new JOptionPane(scrollPane, JOptionPane.ERROR_MESSAGE);
JDialog dialog = jOptionPane.createDialog(parent, "Error");
// it could be nice to let the user resize the dialog, but then the scrollPane always shows the scroll bar
//dialog.setResizable(true);
dialog.setVisible(true);
dialog.dispose();
The size of the scrollPane grows or shrinks. It's maximum is screen size divided by two, or (260, 125) points (just in case the screen is too small :-)). I have found out, that (260, 125) is roughly the size of the empty massage dialog.

pátek 26. června 2009

Eclipse: WTP Plugin and Name of Deployment

I have a WTP project in Eclipse called in like myproject_war. When I have deployed it into the JBoss server, then the deployment name was myproject_war.war. I wanted to deploy it as myproject.war only. I could not find any property in the "Properties" dialogue to change the deploument name, so I have searched my filesystem for "myproject_war" string. So, I have discovered the file
.settings/org.eclipse.wst.common.component in the project directory. I have changed the attribute name of the wb-module module there, from
<wb-module name="myproject_war">
to
<wb-module name="myproject">
Now, the project is deployed as myproject.war.

pátek 19. června 2009

Java: Standalone Pattern and Lazy Initialization with Concurrent Access

Whats wrong with this piece of code?
public class MyClass {
  private static MyClass instance = null;
  public static MyClass getInstance() {
    if (instance == null) instance = new MyClass();
    return instance;
  }
}

Nothing, if you have single thread application only. Otherwise add a magic word synchronized:
public class MyClass {
  private static MyClass instance = null;
  public static synchronized MyClass getInstance() {
    if (instance == null) instance = new MyClass();
    return instance;
  }
}

Now, it's more safe, but a little bit slower. I was thinking about speeding it up by double check locking:
public class MyClass {
  private static MyClass instance = null;
  public static MyClass getInstance() {
    if (instance != null) return instance;
    synchronized (MyClass.class) {
      // yes, one more check in synchronized block
      if (instance == null) instance = new MyClass();
    }
    return instance;
  }
}

Danger! There's hidden snag in this code. Fortunately, I have stumbled upon the See Bill Pugh's page http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html explaining what's wrong with this piece of the code. Briefly, the construction of the object instance = new MyClass() is not an atomic operation. So a thread can get the instance variable while some other thread is still processing the constructor of the same instance object. You can find some old web pages advising to use double check locking in a wrong way, e.g. http://www.javaworld.com/javaworld/javatips/jw-javatip67.html. Bill Pugh's research has changed the memory model in Java 1.5, so there is a new keyword volatile which solves the hidden snag:
public class MyClass {
  private static volatile MyClass instance = null;
  public static MyClass getInstance() {
    if (instance != null) return instance;
    synchronized (MyClass.class) {
      // yes, one more check in synchronized block
      if (instance == null) instance = new MyClass();
    }
    return instance;
  }
}

Java has some nice semantic and syntactic sugar for multi-threaded programming. But this simple example shows, that one should not venture into the Java multi-threaded programming without deeper study of the Java internals and common concurrent programming principles.