Friday, May 29, 2009

Logging in Java

Yes, this is a very basic issue in Java programming, but sometimes it can be really confusing to find where the logs are and how to declaratively configure what to log.

Log4j is widely used and is configured using log4j.properties. But some programmers choose to use Apache commons logging instead of using log4j API directly. Commons logging is a thin-wrapper for other pluggable logging tools, such log4j and Sun logging facility. The configuration guide of commons logging describes a five step procedure to find the underlying logging mechanism, among which, step 3 says:

"If the Log4J logging system is available in the application class path, use the corresponding wrapper class (Log4JLogger)."

In other words, usually even commons logging API is used in the program, the actual logging service is provided by log4j. Thus log4j.properties is used to configure how logging should be done.

Another logging configuration file is logging.properties, which is used by java.util.logging.

Thursday, May 28, 2009

Best Java Decompiler

Recently I am working on a UK e-Science project which uses BPEL to orchestrate web services and submits computational jobs to a condor pool. The source code of some of those web services is missing (great!), so I have to decompile the class files in order to make necessary changes.

In my pursuit of the "best" java decompiler, I first tried JD. It is free. But in my use case, it generates some Java code that can not be compiled. Then I tried DJ. It is good, but it only allows for 10 free trials. Each invocation of DJ is considered to be one trial. After that you have to purchase it.

I hadn't been very happy until I found Jad. Jad did my job. And it turns out that Jad is behind many Java decompiler GUIs such as DJ, Cavaj, and JadClipse, an Eclipse plugin. I am quite happy with Jad even without a GUI to drive it.

It is interesting to see JD and Jad were implemented in C++. Won't it be better for Java programmers to have a Java decompiler written in Java?

Monday, May 04, 2009

Subversive Problem

I am using Subversive - the Eclipse subversion plugin - 0.7.7 plus its subversion connector 2.1.0.

Today an exception jumped out of nowhere, making all my subversion based projects unable to synchronise with the server.

java.lang.NoSuchMethodError: org.eclipse.team.svn.core.connector.SVNChangeStatus.(Ljava/lang/String;Ljava/lang/String;IJJJLjava/lang/String;IIIIZZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;JLorg/eclipse/team/svn/core/connector/SVNLock;JJILjava/lang/String;ZZLorg/eclipse/team/svn/core/connector/SVNConflictDescriptor;)V
at org.tigris.subversion.javahl.ConversionUtility.convert(ConversionUtility.java:287)
at org.tigris.subversion.javahl.ConversionUtility$4.doStatus(ConversionUtility.java:146)
at org.tigris.subversion.javahl.SVNClient.status(Native Method)
at org.polarion.team.svn.connector.javahl.JavaHLConnector.status(JavaHLConnector.java:406)
at org.eclipse.team.svn.core.extension.factory.ThreadNameModifier.status(ThreadNameModifier.java:606)
at org.eclipse.team.svn.core.utility.SVNUtility.status(SVNUtility.java:330)
at org.eclipse.team.svn.core.utility.SVNUtility.getSVNInfoForNotConnected(SVNUtility.java:803)
at org.eclipse.team.svn.core.SVNTeamProvider.uploadRepositoryResource(SVNTeamProvider.java:241)
at org.eclipse.team.svn.core.SVNTeamProvider.connectToProject(SVNTeamProvider.java:172)
at org.eclipse.team.svn.core.SVNTeamProvider.getRepositoryResource(SVNTeamProvider.java:71)
at org.eclipse.team.svn.core.svnstorage.SVNRemoteStorage.loadLocalResourcesSubTreeSVNImpl(SVNRemoteStorage.java:628)
at org.eclipse.team.svn.core.svnstorage.SVNRemoteStorage.loadLocalResourcesSubTree(SVNRemoteStorage.java:521)
at org.eclipse.team.svn.core.svnstorage.SVNRemoteStorage.getRegisteredChildren(SVNRemoteStorage.java:273)
at org.eclipse.team.svn.core.synchronize.AbstractSVNSubscriber.resourcesStateChangedImpl(AbstractSVNSubscriber.java:212)
at org.eclipse.team.svn.core.synchronize.AbstractSVNSubscriber.resourcesStateChanged(AbstractSVNSubscriber.java:169)
at org.eclipse.team.svn.core.svnstorage.SVNRemoteStorage$3.runImpl(SVNRemoteStorage.java:152)
at org.eclipse.team.svn.core.operation.AbstractActionOperation.run(AbstractActionOperation.java:77)
at org.eclipse.team.svn.core.operation.LoggedOperation.run(LoggedOperation.java:38)
at org.eclipse.team.svn.core.utility.ProgressMonitorUtility.doTask(ProgressMonitorUtility.java:104)
at org.eclipse.team.svn.core.utility.ProgressMonitorUtility.doTaskExternal(ProgressMonitorUtility.java:90)
at org.eclipse.team.svn.core.utility.ProgressMonitorUtility$1$1.run(ProgressMonitorUtility.java:60)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1800)
at org.eclipse.team.svn.core.utility.ProgressMonitorUtility$1.run(ProgressMonitorUtility.java:58)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)

The only possible reason that I can think of is I accidentally copied some ".svn" directories into some non-subversion-based project.

On eclipse.technology.subversive Newsgroup, there is a discussion on the same exception, but happen on Subversive 0.7.8.

I am very lucky since after I changed the subversion connector in use from Native JavaHL to SVN Kit, the problem seems gone! Otherwise, all my development work has to stop!