NetBeans 6.8 and OpenOffice 3.3 on Snow Leopard

A quick note to setup working OpenOffice.org plugin development on Mac OS X 10.6 (64bit)…

NetBeans v6.8 (as the last OOo SDK supported version now) works with OpenOffice Extension 2.0.6 (org-openoffice-extensions-2.0.6.nbm) and OpenOffice 3.3 SDK, but NetBeans configuration should be modified to access OpenOffice by Java. You can not create new OpenOffice.org Component (UNO) without this modification, because NetBeans unable to read Service and Interface classes from OOo and results and empty list after several loads of soffice command.

Error log message looks like following, and see why here (issue 110543):

... /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/bin/java[14982]: dlopen(/Volumes/MBP_Addons/Application.Addon/Editors/OpenOffice.org.app/Contents/basis-link/ure-link/lib/libjpipe.jnilib, 1): no suitable image found.  Did find:\n	/Volumes/MBP_Addons/Application.Addon/Editors/OpenOffice.org.app/Contents/basis-link/ure-link/lib/libjpipe.jnilib: mach-o, but wrong architecture

The solution is simple with updating value “netbeans_default_options” in “netbeans.conf” with option “-J-d32”. You can find config file in “NetBeans 6.8.app/Contents/Resources/NetBeans/etc” folder.

Diff properties files

Do you want to find updates in properties files after a new release of an alfresco-like java application? Just see following example script to diff two properties files and show differences…

list_missing_properties.php:

/**
 * Quick sample code to diff two properties files after update
 * see more @ http://louise.hu
 * 
 * Usage:
 * 	php list_missing_properties.php "file1.properties" "file2.properties" 
 * 
 * 
 * @author LouiSe@louise.hu
 */

$ppp = null;

$diff = propertiesDiff($argv[1], $argv[2]);
echo "Properties missing in \"".$argv[2]."\":\n\n";
foreach ($diff as $key => $value){
	echo $value."=".$ppp[$value]."\n";
}
echo "\n\n";

$diff = propertiesDiff($argv[2], $argv[1]);
echo "Properties missing in \"".$argv[1]."\":\n\n";
foreach ($diff as $key => $value){
	echo $value."=".$ppp[$value]."\n";
}
echo "\n";

function getAllPropertyNames($propArray) {
	
	$propertyNames = array();
	
	for($i=0;$i

Java fejlesztés

Hmm, azt hiszem – sőt biztos vagyok benne -, hogy csak akkor érdemes Java-s fejlesztési projektbe fogni, ha a számlázandó összeg végéhez hozzá lehet írni egy nullát… Különben a veszteség igen durva lesz.

Ennél a borzalomnál lassabb, nehézkesebb, erőforrás-zabálóbb idegesítőbb, szögletesebb bullshit-et még nem termelt ki magából ez a bináris előjelű szakma… Java for mazopisták!

Java keystore import on OSX

Do you want to avoid ‘unable to find valid certification path to requested target’ error message of Java applications on OSX?

Just start my shell script with argument of target site name (example below), restart application and enjoy results…

Example error message:

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Source of shell script ssl_key_import_mac.sh:

## JAVA SSL Certificate import script for OSX
## by LouiSe@louise.hu : http://louise.hu
##
## Usage: ./ssl_key_import_mac.sh 
##
## Example: ./ssl_key_import_mac.sh mail.google.com (to read certificate from https://mail.google.com)

## Get java cert downloader source
curl http://blogs.sun.com/andreas/resource/InstallCert.java >InstallCert.java

## Compile and start 
javac InstallCert.java
java InstallCert $1:443

## Copy new cert into local JAVA keystore
echo "Please, enter admnistrator password:"
sudo cp jssecacerts /Library/Java/Home/lib/security/

Source of InstallCert.java:

/*
 * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import java.io.*;
import java.net.URL;

import java.security.*;
import java.security.cert.*;

import javax.net.ssl.*;

public class InstallCert {

    public static void main(String[] args) throws Exception {
	String host;
	int port;
	char[] passphrase;
	if ((args.length == 1) || (args.length == 2)) {
	    String[] c = args[0].split(":");
	    host = c[0];
	    port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
	    String p = (args.length == 1) ? "changeit" : args[1];
	    passphrase = p.toCharArray();
	} else {
	    System.out.println("Usage: java InstallCert [:port] [passphrase]");
	    return;
	}

	File file = new File("jssecacerts");
	if (file.isFile() == false) {
	    char SEP = File.separatorChar;
	    File dir = new File(System.getProperty("java.home") + SEP
		    + "lib" + SEP + "security");
	    file = new File(dir, "jssecacerts");
	    if (file.isFile() == false) {
		file = new File(dir, "cacerts");
	    }
	}
	System.out.println("Loading KeyStore " + file + "...");
	InputStream in = new FileInputStream(file);
	KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
	ks.load(in, passphrase);
	in.close();

	SSLContext context = SSLContext.getInstance("TLS");
	TrustManagerFactory tmf =
	    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
	tmf.init(ks);
	X509TrustManager defaultTrustManager = (X509TrustManager)tmf.getTrustManagers()[0];
	SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
	context.init(null, new TrustManager[] {tm}, null);
	SSLSocketFactory factory = context.getSocketFactory();

	System.out.println("Opening connection to " + host + ":" + port + "...");
	SSLSocket socket = (SSLSocket)factory.createSocket(host, port);
	socket.setSoTimeout(10000);
	try {
	    System.out.println("Starting SSL handshake...");
	    socket.startHandshake();
	    socket.close();
	    System.out.println();
	    System.out.println("No errors, certificate is already trusted");
	} catch (SSLException e) {
	    System.out.println();
	    e.printStackTrace(System.out);
	}

	X509Certificate[] chain = tm.chain;
	if (chain == null) {
	    System.out.println("Could not obtain server certificate chain");
	    return;
	}

	BufferedReader reader =
		new BufferedReader(new InputStreamReader(System.in));

	System.out.println();
	System.out.println("Server sent " + chain.length + " certificate(s):");
	System.out.println();
	MessageDigest sha1 = MessageDigest.getInstance("SHA1");
	MessageDigest md5 = MessageDigest.getInstance("MD5");
	for (int i = 0; i < chain.length; i++) {
	    X509Certificate cert = chain[i];
	    System.out.println
	    	(" " + (i + 1) + " Subject " + cert.getSubjectDN());
	    System.out.println("   Issuer  " + cert.getIssuerDN());
	    sha1.update(cert.getEncoded());
	    System.out.println("   sha1    " + toHexString(sha1.digest()));
	    md5.update(cert.getEncoded());
	    System.out.println("   md5     " + toHexString(md5.digest()));
	    System.out.println();
	}

	System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
	String line = reader.readLine().trim();
	int k;
	try {
	    k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
	} catch (NumberFormatException e) {
	    System.out.println("KeyStore not changed");
	    return;
	}

	X509Certificate cert = chain[k];
	String alias = host + "-" + (k + 1);
	ks.setCertificateEntry(alias, cert);

	OutputStream out = new FileOutputStream("jssecacerts");
	ks.store(out, passphrase);
	out.close();

	System.out.println();
	System.out.println(cert);
	System.out.println();
	System.out.println
		("Added certificate to keystore 'jssecacerts' using alias '"
		+ alias + "'");
    }

    private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();

    private static String toHexString(byte[] bytes) {
	StringBuilder sb = new StringBuilder(bytes.length * 3);
	for (int b : bytes) {
	    b &= 0xff;
	    sb.append(HEXDIGITS[b >> 4]);
	    sb.append(HEXDIGITS[b & 15]);
	    sb.append(' ');
	}
	return sb.toString();
    }

    private static class SavingTrustManager implements X509TrustManager {

	private final X509TrustManager tm;
	private X509Certificate[] chain;

	SavingTrustManager(X509TrustManager tm) {
	    this.tm = tm;
	}

	public X509Certificate[] getAcceptedIssuers() {
	    throw new UnsupportedOperationException();
	}

	public void checkClientTrusted(X509Certificate[] chain, String authType)
		throws CertificateException {
	    throw new UnsupportedOperationException();
	}

	public void checkServerTrusted(X509Certificate[] chain, String authType)
		throws CertificateException {
	    this.chain = chain;
	    tm.checkServerTrusted(chain, authType);
	}
    }

}

Terrible Mac OS X Java vulnerability issue

CVE-2008-5353 allows malicious code to escape the Java sandbox and run arbitrary commands with the permissions of the executing user. This may result in untrusted Java applets executing arbitrary code merely by visiting a web page hosting the applet. The issue is trivially exploitable.

Unfortunately, these vulnerabilities remain in Apple’s shipping JVMs, as well as Soylatte 1.0.3. As Soylatte does not provide browser plugins, the impact of the vulnerability is reduced. The recent release of OpenJDK6/Mac OS X is not affected by CVE-2008-5353.

OSX Java security hole: CVE-2008-5353

Do you want to test your up-to-date Mac OSX installation? Just click here, and enjoy “/usr/bin/say I am executing an innocuous user process” instead of “/bin/rm -rf …”

Links:
CVE-2008-5353
CR0 BLOG: Write once, own everyone, Java deserialization issues
Landon Fuller: Critical Mac OS X Java Vulnerabilities

Barcode reading on PDF pages

I would like to release two useful JAVA functions to help decoding PDF documents to image and scan for barcodes on…

These functions are parts of my Barcode Tools Server, what can recognize and stamp barcodes from/on PDF documents.

Required classes:
JPEDAL (Java Pdf Extraction Decoding Access Library)
J4L Barcode Vision for the Java Platform

PDF2Image: read PDF document from a file, URL or byte array, and render a page with specified resolution (dpi) into an image

public static BufferedImage PDF2Image(String pdfFile, String pdfUrl,
		byte[] pdfArray, int page, int dpi) {

	BufferedImage image = null;

	try {
		PdfDecoder decoder = new PdfDecoder();

		decoder.setExtractionMode(PdfDecoder.RAWIMAGES
				+ PdfDecoder.FINALIMAGES + PdfDecoder.XFORMMETADATA
				+ PdfDecoder.TEXT, dpi, dpi / 72);

		if (pdfFile != null) {
			decoder.openPdfFile(pdfFile);
		} else if (pdfUrl != null) {
			decoder.openPdfFileFromURL(pdfUrl);
		} else if (pdfArray != null) {
			decoder.openPdfArray(pdfArray);
		} else {
			// missing input
			System.err.println("Missing PDF input, please specify a file, an url or a stream");
			return (null);
		}

		// print PDF info
		System.out.println(" Number of pages: "
				+ decoder.getNumberOfPages());
		System.out.println(" Encrypted: " + decoder.isEncrypted());

		if (decoder.isFileViewable()) {
			image = decoder.getPageAsImage(page);
		} else {
			// problem with image!
			System.err.println("Problem with image...");
		}

		decoder.flushObjectValues(true);

		decoder.closePdfFile();
	} catch (Exception err) {
		err.printStackTrace();
	}

	return (image);
}

scanImage: read image and scan for barcodes with specified type (barcodeType)

public static int[] symbologies = new int[] {
		Barcode1DReader.CODE39 | Barcode1DReader.CODE128
				| Barcode1DReader.EAN8 | Barcode1DReader.EAN13
				| Barcode1DReader.IDENTCODE | Barcode1DReader.INTERLEAVED25
				| Barcode1DReader.UPCA | Barcode1DReader.UPCE, // 0 = ALL
		Barcode1DReader.CODE39, // 1
		Barcode1DReader.CODE128, // 2
		Barcode1DReader.EAN8, // 3
		Barcode1DReader.EAN13, // 4
		Barcode1DReader.IDENTCODE, // 5
		Barcode1DReader.INTERLEAVED25, // 6
		Barcode1DReader.UPCA, // 7
		Barcode1DReader.UPCE // 8
};

public static BarcodeData[] scanImage(BufferedImage image, int barcodeType)
		throws Exception {

	// set the system property for minimal barcode image length
	System.setProperty("com.java4less.vision.minbarlength", "10");

	// init barcode reader
	Barcode1DReader bcreader = new Barcode1DReader();

	// set barcode type(s)
	if (barcodeType <= 0 || barcodeType >= symbologies.length) {
		// set all barcode types to scan
		bcreader.setSymbologies(symbologies[0]);
	} else {
		// set one barcode type to scan (faster)
		bcreader.setSymbologies(symbologies[barcodeType]);
	}

	// disable progress view
	bcreader.setProgressListener(null);

	// start barcode scan
	BarcodeData[] barcodes = null;
	try {
		barcodes = bcreader.scan(new RImage((BufferedImage) image));
	} catch (VisionException e) {
		// Error in barcode reader
		e.printStackTrace();
		return (null);
	} finally {

	}

	return (barcodes);
}

My Eclipse installation

Just for a reminder…

Requirements, Features:
– Support for Alfresco development (javascript and java webscripts, actions, properties XMLs)
– HTML editor and preview (Firefox and Safari)
– JavaScript editor (with code formatter, and syntax checker)
– Freemarker editor (with syntax checker)
– PHP editor (with syntax checker and help)
– XML editor
– Shell script editor
– SVN client (projects by checkout)

Eclipse:
Eclipse IDE for Java Developers (3.4 GANYMEDE): download

Tools update site links:
Aptana update for Eclipse 3.4: http://update.aptana.com/update/studio/3.4
– Window menu: My Aptana
Utilities / Subclipse SVN client plugin (with SVNKit)
Platform / Aptana PHP
Platform / Aptana Adobe AIR 1.5 Development
Platform / Aptana Apple iPhone Development
FreeMarker syntax: http://www.freemarker.org/eclipse/update/ (don’t forget to update freemarker.jar in eclipse/plugins/org.visigoths.freemarker_2.3.2)
TRAC plugin for Mylin
Graphviz plugin: http://abstratt.com/update/
– JBOSS jBPM graphical workflow/process designer: unzip “jbpm-jpdl-designer-site.zip” in folder “designer”, then select “Help/Software Updates/Find and Install”, and use “Search for new features to install” to add with “New Local Site”
JSON editor (local site install)
ShellEd – shell script editor (download zip and copy contents into Eclipse directory)

Eclipse with Aptana

Alfresco: ObjID already in use

What a wonderful day, after hours of installation and customization procedure (Alfresco backend on Debian Linux host) i’ve got a killer error message in console.

Alfresco 3.0 startup error, with difficult to understand message about some object what is already in use:

18:46:21,943 ERROR [web.context.ContextLoader.initWebApplicationContext:203] Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.remoting.rmi.RmiServiceExporter' defined in class path resource [alfresco/emailserver/email-service-context.xml]: Invocation of init method failed; nested exception is java.rmi.server.ExportException: internal error: ObjID already in use

The next section of the error log, with network realated messages:

Caused by: java.rmi.server.ExportException: internal error: ObjID already in use
at sun.rmi.transport.ObjectTable.putTarget(ObjectTable.java:169)
at sun.rmi.transport.Transport.exportObject(Transport.java:74)
at sun.rmi.transport.tcp.TCPTransport.exportObject(TCPTransport.java:229)
at sun.rmi.transport.tcp.TCPEndpoint.exportObject(TCPEndpoint.java:393)
at sun.rmi.transport.LiveRef.exportObject(LiveRef.java:129)
at sun.rmi.server.UnicastServerRef.exportObject(UnicastServerRef.java:190)

And what is the solution? Very simple, just check your network and host – in /etc/hosts file – names and IP addresses, and correct to real values, what is showed by ifconfig command.

Java application wants to bind an IP address, but this address isn’t exists on system…