views:

156

answers:

1

I'm running a multi-threaded build with two dependant com.sun.tools.javac.Main.compile() invocations running on separate threads with ~10ms pause between them. Every now (every 100 builds or so), the second javac complains about bad class formats in the outputs from the first javac.

This is on linux, but it has to work on all os'es. What are the constraints I'm facing here?

I'm working on a concurrent build system, so the reason I'm invoking the javacs is because they're in different modules. There is external synchronization that ensures the run-order (but I'm not actually inside a synchronized block when I invoke the compile() method), and I know for sure that they're being invoked one after the other, with approx 10-20ms pause on average. For all I can understand these two calls to compile() should really only be sharing the file system ?

Edit 2: The thread invoking the second compile() call is in a wait() until the first one is finished, so there is order-synchronization. But I'm not inside a synchronized block when I invoke the actual call to compile. Compile is a static method, and I am assuming they don't have any internal safe-publication issues in that context...(?)

Edit 3: Synchronizing the call to compile() does not help. Neither does calling just sync() to linux. But I haven't looked into flushing buffers at the java level if possible.

+2  A: 

What is the javac/java file system concurrency contract ?

There isn't one. If you are compiling a class in thread A that is needed by another compiler in thread B, you shouldn't be. Simple as that.

EJP
According to the nice people at #kernel, linux guarantees visibility of all contents of a file at close() time. So if I fork a separate process I should be home free? Do you have any references to back up the "there isn't one" statement - I'm curious to read more...
krosenvold
You asked about the javac/java contract. If you can find one please let us know. In any case how can you possibly know that thread A will compile the class before thread B needs it?
EJP
Because I wait for thread A to finish before I even start thread B. That is, unless A forks more threads, which I wouldn't know
krosenvold
So why do you need two threads at all in that case?
EJP
EJP; http://incodewetrustinc.blogspot.com/2010/02/concurrency-in-maven.html
krosenvold
That doesn't answer the question. If you are running thread A and waiting for it to finish and then running thread B, why do they have to be threads? You could just essentially do a.run(); b.run() and save yourself all the starts and joins.
EJP
because thread a proceeds to run unit tests for classes in A immediately after finishing compile. same for b.
krosenvold
That still doesn't answer my question.
EJP