javac unzips class files from jars on class path into output directory

Jonathan Gibbons jonathan.gibbons at oracle.com
Thu Mar 9 18:46:28 UTC 2017


-implicit:none is also a good solution, but which solution is best 
depends on your specific situation (i.e. there is no one "best" for 
everyone.)

With -implicit:none, you are allowing javac to determine which kind of 
file to read (source or class) when more than one kind is available for 
any given class, as determined by -Xprefer.  In this case, it would seem 
like javac is choosing to read source files, which may require more 
analysis (i.e. performance cost) than a previously compiled class file.

By setting sourcepath, you are more directly informing javac of where to 
read source files (if any, and if you want that) as compared to class files.

Whether you prefer to have javac read source files or class files 
depends on whether you just want the signatures defined in the class 
file, or whether you want all the info available in the source file, 
and/or whether performance is an issue.

-- Jon

On 03/09/2017 01:13 AM, Doug Simon wrote:
> Jon,
>
> Thanks for the insight. I was not aware (or had forgotten) that the classpath is also searched for source files. Reading the javac man page, it seems like I could also use -implicit:none (I confirmed this works). Is that somehow better/cleaner than an empty source path? Of course, since I control creation of the synthetic jars, I should really just put the sources into a separate zip (a la src.zip in the jdk).
>
> -Doug
>
>> On 9 Mar 2017, at 02:17, Jonathan Gibbons <jonathan.gibbons at oracle.com> wrote:
>>
>> Doug,
>>
>> The jar files in your example contain source code;  therefore javac is not so much copying the contents of the classpath to the output directory as it is compiling the source it is finding.
>>
>> Two experiments for you.
>>
>> 1.
>>
>> $ unzip -l jdk.internal.vm.ci.jar | sort -k 4 | head -n 20
>> ---------                     -------
>>    1710248                     444 files
>> Archive:  jdk.internal.vm.ci.jar
>> ---------  ---------- -----   ----
>>        990  2017-03-07 15:27   jdk/vm/ci/aarch64/AArch64$1.class
>>       7936  2017-03-07 15:27   jdk/vm/ci/aarch64/AArch64.class
>>       1607  2017-03-07 15:27   jdk/vm/ci/aarch64/AArch64$CPUFeature.class
>>       1212  2017-03-07 15:27   jdk/vm/ci/aarch64/AArch64$Flag.class
>>      10478  2017-03-07 15:27   jdk/vm/ci/aarch64/AArch64.java
>>       1414  2017-03-07 15:27   jdk/vm/ci/aarch64/AArch64Kind$1.class
>>       4121  2017-03-07 15:27   jdk/vm/ci/aarch64/AArch64Kind.class
>>       3833  2017-03-07 15:27   jdk/vm/ci/aarch64/AArch64Kind.java
>>        980  2017-03-07 15:27   jdk/vm/ci/amd64/AMD64$1.class
>>       9034  2017-03-07 15:27   jdk/vm/ci/amd64/AMD64.class
>>       2931  2017-03-07 15:27   jdk/vm/ci/amd64/AMD64$CPUFeature.class
>>       1161  2017-03-07 15:27   jdk/vm/ci/amd64/AMD64$Flag.class
>>      11763  2017-03-07 15:27   jdk/vm/ci/amd64/AMD64.java
>>       2207  2017-03-07 15:27   jdk/vm/ci/amd64/AMD64Kind$1.class
>>       5333  2017-03-07 15:27   jdk/vm/ci/amd64/AMD64Kind.class
>>       5384  2017-03-07 15:27   jdk/vm/ci/amd64/AMD64Kind.java
>>
>> 2. In your example, set the sourcepath to be empty. That will force javac to look for source files on the sourcepath (where it won't find any), and only look for class files on the classpath.
>>
>> $ rm -rf bin
>> $ sh run.sh
>> $ find bin
>> bin
>> bin/org
>> bin/org/graalvm
>> bin/org/graalvm/compiler
>> bin/org/graalvm/compiler/api
>> bin/org/graalvm/compiler/api/runtime
>> bin/org/graalvm/compiler/api/runtime/GraalRuntime.class
>> bin/org/graalvm/compiler/api/runtime/GraalJVMCICompiler.class
>> $
>>
>> -- Jon
>>
>>
>> On 03/07/2017 10:11 AM, Doug Simon wrote:
>>> Hi Jon,
>>>
>>> I've attached bug.zip which should reproduce the issue (assuming jdk 9 javac is on your path):
>>>
>>> unzip bug.zip
>>> cd bug
>>> ./run.sh
>>> find bin
>>>
>>> The last command above should show the extra class files from jdk.internal.vm.ci.jar in bin.
>>>
>>> -Doug
>>>
>>>
>>>
>>>
>>>> On 7 Mar 2017, at 18:55, Jonathan Gibbons <jonathan.gibbons at oracle.com>
>>>>   wrote:
>>>>
>>>>
>>>>
>>>> On 03/07/2017 08:06 AM, Doug Simon wrote:
>>>>
>>>>> To be able to develop Graal on JDK 9, we're using the `--release 8` javac option and providing jar files for API that is either not in 9 or is not exported in 9. Here is a simplified form of a javac command:
>>>>>
>>>>> javac -cp jdk.internal.vm.ci.jar:jdk.unsupported_sun.misc.Unsafe.jar -d bin/ --release 8 graal/org.graalvm.compiler.api.runtime/src/org/graalvm/compiler/api/runtime/*.java
>>>>>
>>>>> where:
>>>>>
>>>>> dsimon at kurz-3 ~/h/graal-core> ls graal/org.graalvm.compiler.api.runtime/src/org/graalvm/compiler/api/runtime/*.java
>>>>> graal/org.graalvm.compiler.api.runtime/src/org/graalvm/compiler/api/runtime/GraalJVMCICompiler.java
>>>>> graal/org.graalvm.compiler.api.runtime/src/org/graalvm/compiler/api/runtime/GraalRuntime.java
>>>>>
>>>>> I expect 2 class files to be written to bin/. However, I see a number of files from jdk.internal.vm.ci.jar in bin:
>>>>>
>>>>> dsimon at kurz-3 ~/h/graal-core> jar tf jdk.internal.vm.ci.jar | wc -l
>>>>>       444
>>>>> dsimon at kurz-3 ~/h/graal-core> find bin/jdk/vm/ci | wc -l
>>>>>        55
>>>>>
>>>>> I'm guessing that these are the classes in jdk.internal.vm.ci.jar referenced (transitively?) from the Graal sources.
>>>>>
>>>>> Why is this happening? That is, why is javac extracting classes from a jar on the classpath and putting them in the output directory?
>>>>>
>>>>> -Doug
>>>>>
>>>> Doug,
>>>>
>>>> Can you provide a more complete test case?
>>>>
>>>> -- Jon
>>>>



More information about the jigsaw-dev mailing list