views:

472

answers:

4

I'm using ant 1.8.0 and java 1.6.0.17 and I'm running into a strange problem.

In my build.xml, I have a simple task that compiles the code

<javac destdir="${dir.build.classes}" debug="on">
    <classpath refid="classpath"/>
    <src path="${dir.src.java}"/>
</javac>

In the "classpath" is a jar, call it library.jar

In a later task, I need to add a few classes to library.jar, which I do like this

<jar destfile="library.jar" update="true" duplicate="fail">
    <fileset dir="${dir.build.classes}">
        <include name="some/class/files"/>
    </fileset>
</jar>

This will fail with the error Unable to rename old file (library.jar) to temporary file

I stuck in a call to handle.exe before and after the javac call, and I can confirm that the java process running ant grabs a file handle to library.jar during the javac call, and it doesn't give it up. This causes my later attempt to update the jar to fail.

Why would ant keep a handle to the jar in a classpath open even after the javac task is complete?

+1  A: 

This is a windows locking issue. Any process/thread reading the file will prevent it from being renamed, which is what the zip task is doing, when updating an existing jar file.

I'm guessing that the file handle is being kept open because your using a classpath reference. Maybe the file handles might be closed if you were to explicitly set the javac task's classpath?

Mark O'Connor
Can you explain what you mean by "explicitly set the javac task's classpath" ? It's a rather large set of jars that is used in several other places, so hard-coding them isn't really an option, and I'm not sure why it would make a difference.
karoberts
A: 

So I found the answer, after some experimentation. By adding fork="true" to my javac task, the file handle is closed at the end of the task. This allows my jar modification to succeed later in the build.

It's unfortunate though, because I have to remember to add this to every upstream javac task.

karoberts
A: 

It seems related to classpath configuration and The first operation on the jar file keeps it opened. I've resolved this issue by removing "." from my classpath env variable.