Poor Man’s CMS 2.4RC1 released

In this release the backend has changed dramatically. The data store has changed from a database to plain xml files. This is increasing the speed enormously.

The ftp password is now stored encrypted in the backup file. That’s why you have to set your password again. You will get a corresponding hint. It is essential to make a clean installation, the data directory must be removed!!!

I don’t have the time to concentrate on testing on different platforms. That’s the reason why I’ll deploy only release candidates from now on.
If you find bugs don’t hesitate to file a ticket here or leave a comment in the forum.

The changes in detail:

fixes:

  • the location settings and composition of the HeapSizeDialog is wrong

features and improvements:

  • ftp-password is encrypted in the backup and data xml
  • feature #44 big refactoring: use XML file per site instead of database, more use of spring pattern
  • integrated jii

internal:

  • updated commons-net to 2.2
  • updated velocity to 1.7
  • updated spring to 3.0.5
  • updated swt to 3.7 and dependent libs

, ,

Leave a Comment

JII (Java Image Info)

I’ve just published my 2nd open source project: JII (Java Image Info)

It provides a clean interface to a collection of Java libraries and source code that reads basic properties of images. The focus is on the following image types which are relevant for the web:

  • BMP
  • GIF
  • JPEG
  • PNG

The indention for this project to check which is the best way to do this for my project. Because of the clean interface, it is very easy to switch between different implementations.

,

Leave a Comment

Proper handling of the ProcessBuilder

I had good experiences with the ProcessBuilder to call native commands. That’s why I would like to use it for another project. But testing it in the new project environment, it often hung.

But why and what’s the difference to the other project? It was the quantity of output.

In the JDK documentation of the Process I’ve found right hint:

The parent process uses these streams (#getInputStream(), #getErrorStream()) to feed input to and get output from the subprocess. Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.

That means: The streams must be read!!! Depending on the native platform, the quantity of output (info or error, what ever) can cause a buffer overflow and therefore an hanging Process.

The code above shows is a wrapper to the ProcessBuilder which boozes the streams:

/**
 * GPL
 */
public class ProcessBuilderWrapper {
	private StringWriter infos;
	private StringWriter errors;
	private int status;
	
	public ProcessBuilderWrapper(File directory, List<String> command) throws Exception {
		infos = new StringWriter();
		errors = new StringWriter();
		ProcessBuilder pb = new ProcessBuilder(command);      
		if(directory != null)
			pb.directory(directory);
		Process process = pb.start();
		StreamBoozer seInfo = new StreamBoozer(process.getInputStream(), new PrintWriter(infos, true));
		StreamBoozer seError = new StreamBoozer(process.getErrorStream(), new PrintWriter(errors, true));
		seInfo.start();
		seError.start();
		status = process.waitFor();		
	}

	public ProcessBuilderWrapper(List<String> command) throws Exception {
		this(null, command);
	}
	
	public String getErrors() {
		return errors.toString();
	}
	
	public String getInfos() {
		return infos.toString();
	}
	
	public int getStatus() {
		return status;
	}

	class StreamBoozer extends Thread {
		private InputStream in;
		private PrintWriter pw;
		
		StreamBoozer(InputStream in, PrintWriter pw) {
			this.in = in;
			this.pw = pw;
		}
		
		@Override
		public void run() {
			BufferedReader br = null;
			try {
				br = new BufferedReader(new InputStreamReader(in));
				String line = null;
	            while ( (line = br.readLine()) != null) {
	            	pw.println(line);
	            }
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}	

Example:
List<String> cmd = new ArrayList<String>();
cmd.add("ls");
cmd.add("-al");
ProcessBuilderWrapper pbd = new ProcessBuilderWrapper(new File("/tmp"), cmd);
System.out.println("Command has terminated with status: " + pbd.getStatus());
System.out.println("Output:\n" + pbd.getInfos());
System.out.println("Error: " + pbd.getErrors());

, ,

Leave a Comment

How to uninstall xulrunner on OS X?

A view week ago, I had a nasty problem. I updated my xulrunner installation to 7.0. A software project based on xulrunner wouldn’t run with this version. Ok, back to the old one. But how? The installer of the new hasn’t any uninstall option and the installer of the old one was canceling, because a newer version exists.

Googleing around I’ve found a few hints but none of them works correctly or wasn’t the half line.

To delete the whole xulrunner manually you have to delete the following items:

  • Directory: /Library/Frameworks/XUL.framework/
  • File: /private/var/db/receipts/org.mozilla.xulrunner.bom (seems relevant to 10.6.7)
  • File: /private/var/db/receipts/org.mozilla.xulrunner.plist (seems relevant to 10.6.7)
  • File: /Library/Receipts/xulrunner-*.mac.pkg

,

Leave a Comment

Getting and Extending mime-types in Java

Working with mime-types (e.g. in your own servlet environment) is very easy, if you know the basics implemented in Java. The main object we need is the java.net.FileNameMap. Its method #getContentTypeFor(String fileName) returns the mime-type for the desired filename. You can get a default implementation of FileNameMap from java.net.URLConnection#getFileNameMap(). (Btw: There are different subclasses of URLConnection to handle jars or URLs.)

The default mime-types are generally read from the properties file JAVA_HOME/lib/content-types.properties. There you can find only the most important ones, not really useable in a complex servlet environment. But you can copy this properties file, adapt it to your special needs and force the URLConnection to load it. You just have to set the system property content.types.user.table to your own properties file.

,

Leave a Comment

Follow

Get every new post delivered to your Inbox.