From srikanth.adayapalam at oracle.com Thu Dec 3 05:28:28 2015 From: srikanth.adayapalam at oracle.com (Srikanth) Date: Thu, 03 Dec 2015 10:58:28 +0530 Subject: Annotations on lambda parameters and captured outer locals. Message-ID: <565FD2FC.4020002@oracle.com> Hello ! The prose in the description of JDK-8138729 read in conjunction with JDK-8140279 would seem to require that - Declaration and type annotations from the captured outer locals of a lambda expression are not to be transmitted to the formal parameter (that represents/reifies the captured local variable) of the synthetic lambda implementation method[*] - Declaration annotations on a lambda formal should not make it to the class file at all. - Type annotations on the type of a lambda formal should be carried over to the type of the formal parameter of the synthetic method that implements the lambda[*] Is this correct ? I have no problems implementing this, but it does read a bit irregular. A confirmation that this is all reasoned out and intentional would help. [*] if that is the translation strategy/tactic chosen by a compiler. Thanks in advance, Srikanth From alex.buckley at oracle.com Thu Dec 3 23:23:10 2015 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 03 Dec 2015 15:23:10 -0800 Subject: Annotations on lambda parameters and captured outer locals. In-Reply-To: <565FD2FC.4020002@oracle.com> References: <565FD2FC.4020002@oracle.com> Message-ID: <5660CEDE.6050803@oracle.com> On 12/2/2015 9:28 PM, Srikanth wrote: > The prose in the description of JDK-8138729 read in conjunction with > JDK-8140279 would seem to require that > > - Declaration and type annotations from the captured outer locals > of a lambda > expression are not to be transmitted to the formal parameter > (that represents/reifies > the captured local variable) of the synthetic lambda > implementation method[*] Yes. No-one should be relying on any aspect of this formal parameter. Transmitting declaration annotations to it, or type annotations to its type, would be an attractive nuisance. > - Declaration annotations on a lambda formal should not make it to the > class file at all. Yes. The true intent of JSR 335 was that declaration annotations on a lambda formal should be source-only, like declaration annotations on a local variable. JLS9 will clarify this, via JDK-8140279. > - Type annotations on the type of a lambda formal should be carried > over to the type > of the formal parameter of the synthetic method that implements > the lambda[*] Yes. Specifically on this point, Brian said "I'm OK that type annotations travel with their type uses, because dataflow analysis can still be useful against such classfiles (which was the point of type annos) without turning this into a metaprogramming framework." Alex From asviraspossible at gmail.com Fri Dec 4 08:51:28 2015 From: asviraspossible at gmail.com (Victor Nazarov) Date: Fri, 4 Dec 2015 11:51:28 +0300 Subject: Using error-types in annotation processors In-Reply-To: <565CC316.40000@oracle.com> References: <565CC316.40000@oracle.com> Message-ID: Jonathan, thank you for your reply. Can I personally file this bug? It seems that I have no access to https://bugs.openjdk.java.net/ . Is there a way I can somehow track this bug status? -- Victor Nazarov On Tue, Dec 1, 2015 at 12:43 AM, Jonathan Gibbons < jonathan.gibbons at oracle.com> wrote: > cc: compiler-dev > bcc: anno-pipeline-dev > > That being said, it seems like this is a bug/rfe that should be filed and > fixed. > > -- Jon > > > > On 11/27/2015 05:36 AM, Victor Nazarov wrote: > >> Hello, >> >> I hope that this is an appropriate place to write my question. >> >> To add some context, I'm a developer of [adt4j]( >> https://github.com/sviperll/adt4j) project. >> >> Java compiler pass every reference to unknown classes as an "error" type. >> But it can be useful to inspect such error-types in annotation processor >> to >> actually generate missing classes. This somewhat works in latest JDK8, but >> not in the special case interesting for adt4j project. >> >> The way to inspect error type is to use methods provided by >> ErrorType-class. There are only two interesting ways to inspect error >> type: >> >> errorType.asElement().getSimpleName() --- to get the name of missing class >> errorType.getTypeArguments() --- to get type-arguments applied to >> type-to-be. >> >> The problem is that sometimes these methods provide no useful information. >> In such situation getSimpleName method returns useless "" string and >> no feather processing is possible. >> >> Suppose that we want to generate class MyClassToGenerate and it is >> currently missing. Below are some code snippets. With Example1, Example2 >> and Example3 error-type processing works as expected. Example4 doesn't >> work >> as expected and always returns "" string. This looks inconsistent and >> I'd be glad if it can be fixed in future versions of Java... >> >> Example1 >> -------------- >> class MyClass extends MyClassToGenerate { >> } >> >> Example2 >> -------------- >> class MyClass extends MyClassToGenerate { >> } >> >> Example3 >> -------------- >> class MyClass { >> void method1(MyClassToGenerate argument) { >> } >> } >> >> Example4 >> -------------- >> class MyClass { >> void method1(MyClassToGenerate argument) { >> } >> } >> >> -- >> Victor Nazarov >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From srikanth.adayapalam at oracle.com Sat Dec 5 04:33:20 2015 From: srikanth.adayapalam at oracle.com (Srikanth) Date: Sat, 05 Dec 2015 10:03:20 +0530 Subject: Build failure: langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java:1735 In-Reply-To: References: Message-ID: <56626910.8010907@oracle.com> Can you try make clean first ? I think this code is referencing some methods that belong in a type (CompilerProperties.java) that gets generated by an earlier rule - perhaps there is some bug in the build scripts that causes the regeneration of CompilerProperties.java to be bypassed. Thanks! Srikanth On Tuesday 01 December 2015 04:12 AM, Carsten Varming wrote: > Dear compiler-dev list, > > I was trying to build the tip of the jdk9-rt forest today and ran into > this failure: > > /home/cvarming/workspace/jdk9-rt/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java:1735: > error: cannot find symbol > Errors.OverrideIncompatibleRet(Fragments.CantHide(m, m.location(), other, > ^ > symbol: method CantHide(MethodSymbol,Symbol,MethodSymbol,Symbol) > location: class Fragments > 1 error > > If I go back to 3094:3449ae78c6dc in the langtools repo, then > everything works, but any later commit is broken. > > Is this a known issue where I simply need to wait a few days for a fix > to appear? > > Carsten From forax at univ-mlv.fr Sat Dec 5 19:46:53 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Sat, 5 Dec 2015 20:46:53 +0100 (CET) Subject: Inverse annotation inheritance issue with generic interfaces In-Reply-To: <5643E389.3020003@online.de> References: <5643E389.3020003@online.de> Message-ID: <1564689402.2536887.1449344813416.JavaMail.zimbra@u-pem.fr> Hi Lukas, First, reflection do not provide runtime objects for Java the language constructions but for VM class format constructions. And sometimes, the Java view and the bytecode view are slightly different. What you are seeing in your example is the introduction by the compiler of a bridge method (you can google it for more info), that is generated by the compiler in order to support the case of a class that implements a generic interface with a type parameter/type argument with a different bound. The OpenJDK7 compiler you use has a bug because a bridge method should not have annotation attached to it, you can easily fix the issue by filter out the method that are marked as bridge method [1]. cheers, R?mi [1] http://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Method.html#isBridge-- ----- Mail original ----- > De: "Lukas Magel" > ?: compiler-dev at openjdk.java.net > Envoy?: Jeudi 12 Novembre 2015 01:55:37 > Objet: Inverse annotation inheritance issue with generic interfaces > > Hello, > > I am currently working on a JAVA EE web project and have been > experiencing a compiler behavior which I don't know how to interpret. > > In our code we define interfaces like the following: > > public interface SampleInterface { > > public void sampleMethod(T t); > > } > > as well as an implementing class: > > public class Main implements SampleInterface { > > @SampleAnnotation > public void sampleMethod(B t) { > > } > } > > and the corresponding annotation: > > @Retention(RetentionPolicy.RUNTIME) > @Target(ElementType.METHOD) > public @interface SampleAnnotation { > > } > > Where Class B extends A. All classes are compiled using the OpenJDK7 > compiler. If I use Reflection to retrieve all methods of the Main class > at runtime and print each method with its annotations I get the > following list of methods: > > class Main > > public void Main.sampleMethod(A) > @SampleAnnotation() > > public void Main.sampleMethod(B) > @SampleAnnotation() > > The compiler will assign the annotation to the method declaration of the > interface although the annotation is only declared in the implementing > class. I cannot reproduce this behavior with the Oracle Java Compiler or > the Eclipse JDT Compiler. If I compile the example with one of the two > compilers the resulting program will yield the following result: > > class annotation.Main > > public void annotation.Main.sampleMethod(annotation.A) > > public void annotation.Main.sampleMethod(annotation.B) > @annotation.SampleAnnotation() > > The JRE type (Oracle, OpenJDK) that the program is executed with has no > influence on the result. > > My actual question is whether this behavior is intended or not because > it causes quite some issues with our JAXRS REST implementations. All > REST classes each implement an interface like the one above and are > annotated with multiple annotations to allow the container to identify > endpoints at runtime. The JAXRS framework uses reflection to determine > possible method candidates at runtime and will happily accept both the > generic and the special method since both of the carry the annotations. > > I can also provide an example project if necessary. > > Thanks, > Lukas > From cushon at google.com Mon Dec 7 21:09:42 2015 From: cushon at google.com (Liam Miller-Cushon) Date: Mon, 7 Dec 2015 13:09:42 -0800 Subject: RFR: 8059976 Convert JavacFileManager to use java.nio.file internally In-Reply-To: <55DCFD6D.7010401@oracle.com> References: <55A03ED4.6040201@oracle.com> <55A03FD7.7020604@oracle.com> <55A04629.4050401@oracle.com> <55DCFD6D.7010401@oracle.com> Message-ID: On Tue, Aug 25, 2015 at 4:42 PM, Jonathan Gibbons < jonathan.gibbons at oracle.com> wrote: > I'd be particularly interested in feedback from folk developing custom > file managers based on top of nio FileSystems. Sorry for the belated feedback. I just migrated some tests from JavacPathFileManager to use these changes, and the only issue I encountered is that JavacFileManager#asPath doesn't handle PathFileObjects. I think it's just missing: } else if (file instanceof PathFileObject) { return ((PathFileObject) file).getPath(); Everything else looks great. Thanks! -------------- next part -------------- An HTML attachment was scrubbed... URL: From joe.darcy at oracle.com Tue Dec 8 00:47:13 2015 From: joe.darcy at oracle.com (Joseph D. Darcy) Date: Mon, 07 Dec 2015 16:47:13 -0800 Subject: Using error-types in annotation processors In-Reply-To: <565CC316.40000@oracle.com> References: <565CC316.40000@oracle.com> Message-ID: <56662891.6020908@oracle.com> Hello, On 11/30/2015 1:43 PM, Jonathan Gibbons wrote: > cc: compiler-dev > bcc: anno-pipeline-dev > > That being said, it seems like this is a bug/rfe that should be filed > and fixed. > > -- Jon > > > On 11/27/2015 05:36 AM, Victor Nazarov wrote: >> Hello, >> >> I hope that this is an appropriate place to write my question. >> >> To add some context, I'm a developer of [adt4j]( >> https://github.com/sviperll/adt4j) project. >> >> Java compiler pass every reference to unknown classes as an "error" >> type. >> But it can be useful to inspect such error-types in annotation >> processor to >> actually generate missing classes. This somewhat works in latest >> JDK8, but >> not in the special case interesting for adt4j project. >> >> The way to inspect error type is to use methods provided by >> ErrorType-class. There are only two interesting ways to inspect error >> type: >> >> errorType.asElement().getSimpleName() --- to get the name of missing >> class >> errorType.getTypeArguments() --- to get type-arguments applied to >> type-to-be. >> >> The problem is that sometimes these methods provide no useful >> information. >> In such situation getSimpleName method returns useless "" string >> and >> no feather processing is possible. >> >> Suppose that we want to generate class MyClassToGenerate and it is >> currently missing. Below are some code snippets. With Example1, Example2 >> and Example3 error-type processing works as expected. Example4 >> doesn't work >> as expected and always returns "" string. This looks >> inconsistent and >> I'd be glad if it can be fixed in future versions of Java... [snip] FYI, the behavior of the javax.lang.model.* objects in annotation procession in the presence of incomplete / incorrect programs was a challenging part of the specification. After much consideration, the text we ended up with was: > During annotation processing, operating on incomplete or erroneous > programs is necessary; however, there are fewer guarantees about the > nature of the resulting model. If the source code is not syntactically > well-formed or has some other irrecoverable error that could not be > removed by the generation of new types, a model may or may not be > provided as a quality of implementation issue. If a program is > syntactically valid but erroneous in some other fashion, any returned > model must have no less information than if all the method bodies in > the program were replaced by |"throw new RuntimeException();"|. If a > program refers to a missing type XYZ, the returned model must contain > no less information than if the declaration of type XYZ were assumed > to be |"class XYZ {}"|, |"interface XYZ {}"|, |"enum XYZ {}"|, or > |"@interface XYZ {}"|. If a program refers to a missing type |XYZ ... ,Kn>|, the returned model must contain no less information than if > the declaration of XYZ were assumed to be |"class XYZ > {}"| or |"interface XYZ {}"| http://docs.oracle.com/javase/8/docs/api/javax/lang/model/element/package-summary.html Cheers, -Joe -Joe -------------- next part -------------- An HTML attachment was scrubbed... URL: From mernst at cs.washington.edu Wed Dec 9 01:09:16 2015 From: mernst at cs.washington.edu (Michael Ernst) Date: Tue, 08 Dec 2015 17:09:16 -0800 (PST) Subject: TYPE_USE annotations on type parameter declarations Message-ID: <20151208.170916.2090458523492272288.mernst@cs.washington.edu> I have a question about use of TYPE_USE annotations on type parameter declarations. I did not expect this code to compile: @Target(ElementType.TYPE_USE) @interface TU { } // This is surprising: public class TypeUseAtParameter<@TU T> { } because I thought that a @Target(TYPE_USE) annotation could not be written on the declaration of a type parameter. In fact, javac (from JDK 8 or JDK 9) accepts it. See the attachment for a full, compilable test case. Section 9.6.4.1 says, "There are 16 type contexts (?4.11), all represented by the enum constant TYPE_USE of java.lang.annotation.ElementType.", and section 4.11 does not include a type parameter declaration as one of these locations. Am I confused, or may there be a problem with javac? Thanks! -Mike -------------- next part -------------- import java.lang.annotation.ElementType; import java.lang.annotation.Target; @Target(ElementType.TYPE_USE) @interface TU { } @Target(ElementType.TYPE_PARAMETER) @interface TP { } // This is surprising: public class TypeUseAtParameter<@TU T> { } // This is expected: class TypeParameterAtParameter<@TP T> { } From alex.buckley at oracle.com Wed Dec 9 01:48:38 2015 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 08 Dec 2015 17:48:38 -0800 Subject: TYPE_USE annotations on type parameter declarations In-Reply-To: <20151208.170916.2090458523492272288.mernst@cs.washington.edu> References: <20151208.170916.2090458523492272288.mernst@cs.washington.edu> Message-ID: <56678876.1040800@oracle.com> On 12/8/2015 5:09 PM, Michael Ernst wrote: > I did not expect this code to compile: > > @Target(ElementType.TYPE_USE) > @interface TU { } > > // This is surprising: > public class TypeUseAtParameter<@TU T> { > } > > because I thought that a @Target(TYPE_USE) annotation could not be > written on the declaration of a type parameter. In fact, javac (from > JDK 8 or JDK 9) accepts it. See the attachment for a full, compilable > test case. > > Section 9.6.4.1 says, "There are 16 type contexts (?4.11), all > represented by the enum constant TYPE_USE of > java.lang.annotation.ElementType.", and section 4.11 does not include a > type parameter declaration as one of these locations. > > Am I confused, or may there be a problem with javac? Recall from java-annotation-design.pdf that: --- ElementType.TYPE_USE stands for all uses of types, plus two special cases. 1. A type annotation (one meta-annotated with @Target(ElementType.TYPE_USE)) is permitted to be written anywhere @Target(ElementType.TYPE) or @Target(ElementType.TYPE_PARAMETER) would permit ? that is, on a class, interface, or enum declaration, or on a type parameter declaration. Strictly speaking, these are declaration sites, not uses of a type. However, it is convenient to write a type annotation at a type declaration, as shorthand for applying it at all uses. For example, @Interned class MyClass { ... } could indicate that all uses of MyClass are interned, even though for other classes some instances may be interned and other instances not interned. --- As a result, JLS8 9.7.4 says: --- It is a compile-time error if an annotation of type T is syntactically a modifier for: - a class, interface, or enum declaration, but T is not applicable to type declarations or type contexts; or an annotation type declaration, but T is not applicable to annotation type declarations or type declarations or type contexts. - a type parameter declaration of a generic class, interface, method, or constructor, but T is not applicable to type parameter declarations or type contexts. --- These clauses mention "or type contexts" to implement the policy that an annotation whose own type has @Target(ElementType.TYPE_USE) can be written in locations where you might expect to find only an annotation whose own type is @Target(ElementType.TYPE) or @Target(ElementType.TYPE_PARAMETER). So, javac is fine. Unfortunately, while reviewing 9.7.4: --- A declaration annotation is an annotation that applies to a declaration, and whose own type is applicable in the declaration context (?9.6.4.1) represented by that declaration. A type annotation is an annotation that applies to a type (or any part of a type), and whose own type is applicable in type contexts (?4.11). --- I found a hole: - The annotation @TU is not a "declaration annotation" because while it applies to a declaration, its own type TU is not applicable in the declaration context represented by the class/interface/enum/annotation-type/type-parameter declaration. - The annotation @TU is not considered a "type annotation" because it does not apply to a type use. This failure to classify the annotation is bad. Let's see what javac emits for a TYPE_USE annotation like @TU: - On a class/interface/enum/annotation-type declaration, javac emits a Runtime[In]VisibleAnnotations attribute -- this makes sense as it's basically a traditional declaration annotation. - On a type-parameter declaration, javac emits a Runtime[In]VisibleTypeAnnotations attribute -- that's the only way to encode the annotation, but still we should regard it as a declaration annotation (that's how Core Reflection exposes it). Consequently, 9.7.4 should add a paragraph: --- ***Additionally, an annotation that applies to either: - a class, interface, enum, or annotation type declaration, or - a type parameter declaration of a generic class, interface, method, or constructor and whose own type is applicable in type contexts, is deemed to be a declaration annotation.*** --- Alex From jonathan.gibbons at oracle.com Wed Dec 9 03:10:57 2015 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Tue, 08 Dec 2015 19:10:57 -0800 Subject: RFR: 8059976 Convert JavacFileManager to use java.nio.file internally In-Reply-To: References: <55A03ED4.6040201@oracle.com> <55A03FD7.7020604@oracle.com> <55A04629.4050401@oracle.com> <55DCFD6D.7010401@oracle.com> Message-ID: <56679BC1.1050307@oracle.com> On 12/07/2015 01:09 PM, Liam Miller-Cushon wrote: > On Tue, Aug 25, 2015 at 4:42 PM, Jonathan Gibbons > > wrote: > > I'd be particularly interested in feedback from folk developing > custom file managers based on top of nio FileSystems. > > > Sorry for the belated feedback. I just migrated some tests from > JavacPathFileManager to use these changes, and the only issue I > encountered is that JavacFileManager#asPath doesn't handle > PathFileObjects. I think it's just missing: > > } else if (file instanceof PathFileObject) { > return ((PathFileObject) file).getPath(); > > Everything else looks great. > > Thanks! Thanks for the feedback. As for .asPath, the recent changeset for 8059976 [1] covered this: @Override @DefinedBy(Api.COMPILER) public Path asPath(FileObject file) { if (file instanceof PathFileObject) { return ((PathFileObject) file).path; } else throw new IllegalArgumentException(file.getName()); } -- Jon [1] http://hg.openjdk.java.net/jdk9/dev/langtools/rev/30e288cb2d22 -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex.buckley at oracle.com Wed Dec 9 19:31:35 2015 From: alex.buckley at oracle.com (Alex Buckley) Date: Wed, 09 Dec 2015 11:31:35 -0800 Subject: TYPE_USE annotations on type parameter declarations In-Reply-To: <56678876.1040800@oracle.com> References: <20151208.170916.2090458523492272288.mernst@cs.washington.edu> <56678876.1040800@oracle.com> Message-ID: <56688197.5030109@oracle.com> On 12/8/2015 5:48 PM, Alex Buckley wrote: > Unfortunately, while reviewing 9.7.4: > > --- > A declaration annotation is an annotation that applies to a declaration, > and whose own type is applicable in the declaration context (?9.6.4.1) > represented by that declaration. > > A type annotation is an annotation that applies to a type (or any part > of a type), and whose own type is applicable in type contexts (?4.11). > --- > > I found a hole: > > - The annotation @TU is not a "declaration annotation" because while it > applies to a declaration, its own type TU is not applicable in the > declaration context represented by the > class/interface/enum/annotation-type/type-parameter declaration. > > - The annotation @TU is not considered a "type annotation" because it > does not apply to a type use. > > This failure to classify the annotation is bad. Let's see what javac > emits for a TYPE_USE annotation like @TU: > > - On a class/interface/enum/annotation-type declaration, javac emits a > Runtime[In]VisibleAnnotations attribute -- this makes sense as it's > basically a traditional declaration annotation. > > - On a type-parameter declaration, javac emits a > Runtime[In]VisibleTypeAnnotations attribute -- that's the only way to > encode the annotation, but still we should regard it as a declaration > annotation (that's how Core Reflection exposes it). > > Consequently, 9.7.4 should add a paragraph: > > --- > ***Additionally, an annotation that applies to either: > > - a class, interface, enum, or annotation type declaration, or > - a type parameter declaration of a generic class, interface, method, or > constructor > > and whose own type is applicable in type contexts, is deemed to be a > declaration annotation.*** > --- Tracked via https://bugs.openjdk.java.net/browse/JDK-8145032. Alex From srikanth.adayapalam at oracle.com Thu Dec 10 04:19:09 2015 From: srikanth.adayapalam at oracle.com (Srikanth) Date: Thu, 10 Dec 2015 09:49:09 +0530 Subject: Questions about type annotation on type casts. Message-ID: <5668FD3D.5050403@oracle.com> Hello experts, JLS-meisters, While working on https://bugs.openjdk.java.net/browse/JDK-8144168, a few questions have surfaced regarding code generation for a type annotated cast. (1) If the expression that is being type-cast and the target type of the cast are determined to be the same at compile time, javac does not emit a checkcast instruction at all. This looks lossy to me. ECJ always emits a cast if there is a type annotation involved. Which approach is also problematic since ... (2) ... Since checkcast necessarily works only on reference operands on the stack. So ECJ ends up generating bad code for import java.lang.annotation.*; public class X { @Target(ElementType.TYPE_USE) public @interface T { } public static void main(String[] args) { int i = (@T int) 10; } } attempting to emit a checkcast due to the policy of an annotated cast always being emitted into the classfile. (3) JVMS 4.7.20.1 states: ... type_argument_target { u2 offset; u1 type_argument_index; } The value of the offset item specifies the code array offset of either the bytecode instruction corresponding to the cast expression, the new bytecode instruction corresponding to the new expression, ... So what exactly intended to be the value of the offset item for a cast ? ATM, javac seems to interpret this as the offset of the first instruction of chunk of code generated to evaluate the the expression being typecast, while ECJ makes the offset point to the checkcast instruction itself. Thanks in advance for any clarifications. Srikanth From shaojian.yu at hotmail.com Thu Dec 10 11:42:16 2015 From: shaojian.yu at hotmail.com (yu shaojian) Date: Thu, 10 Dec 2015 19:42:16 +0800 Subject: Learn about javac Message-ID: Hi all, I?am a beginner for javac, if I want to know more about it, what should I do? Thanks. ??? Windows 10 ????? -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Thu Dec 10 11:56:58 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 10 Dec 2015 11:56:58 +0000 Subject: Learn about javac In-Reply-To: References: Message-ID: <5669688A.9060606@oracle.com> Hi, glad to hear you wanna know more about the compiler; this page: http://openjdk.java.net/groups/compiler/ is full of useful links; they contain both blog entries that are related to javac and some high level documentation on how the codebase is structured (i.e. what are the main compilation phases etc.). This should give you a rough idea of who's doing what and can be used as a reference guide when browsing through the code base. Good luck! Maurizio On 10/12/15 11:42, yu shaojian wrote: > > Hi all, > > I?am a beginner for javac, if I want to know more about it, > what should I do? Thanks. > > ???Windows 10 ??? /?LinkId=550986>? ? > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bsrbnd at gmail.com Thu Dec 10 13:50:06 2015 From: bsrbnd at gmail.com (bsrbnd) Date: Thu, 10 Dec 2015 14:50:06 +0100 Subject: Symbolic annotation processor Message-ID: Hi, Following our discussion (October 2015), I wrote an annotation-processor (only a draft for now) that gives a symbolic view of class members, for example: @Symbolic private Object myField; @Symbolic("_") private void myMethod(Object param) {} We can either access the name or the reflective object of members the following way: String name = $myField.toString(); // $ is the default prefix Method m = _myMethod.reflect(); // _ is a custom prefix, useful for overloaded identifiers You can find a simple example here: https://github.com/bsrbnd/draft/blob/master/src/examples/Example.java Full source code of the annotation-processor prototype is given there: https://github.com/bsrbnd/draft Comments are welcome, but I know this is probably not the right mailing-list for that. Regards, Bernard From jonathan.gibbons at oracle.com Thu Dec 10 18:52:28 2015 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Thu, 10 Dec 2015 10:52:28 -0800 Subject: Learn about javac In-Reply-To: References: Message-ID: <5669C9EC.9080304@oracle.com> On 12/10/2015 03:42 AM, yu shaojian wrote: > > Hi all, > > I?am a beginner for javac, if I want to know more about it, > what should I do? Thanks. > > ???Windows 10 ??? /?LinkId=550986>? ? > Are you looking to know more about how to use it, or about how it works internally? If you are just looking to use javac, googling "jdk 8 javac" brings up the following good link: https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html If you are looking to know more about the internals, see Maurizio's response to your question. -- Jon -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex.buckley at oracle.com Fri Dec 11 00:25:36 2015 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 10 Dec 2015 16:25:36 -0800 Subject: Questions about type annotation on type casts. In-Reply-To: <5668FD3D.5050403@oracle.com> References: <5668FD3D.5050403@oracle.com> Message-ID: <566A1800.1010104@oracle.com> On 12/9/2015 8:19 PM, Srikanth wrote: > While working on https://bugs.openjdk.java.net/browse/JDK-8144168, > a few questions have surfaced regarding code generation for a type > annotated cast. > > (1) If the expression that is being type-cast and the target type of the > cast > are determined to be the same at compile time, javac does not emit a > checkcast instruction at all. This looks lossy to me. ECJ always emits a > cast if there is a type annotation involved. Which approach is also > problematic since ... > > (2) ... Since checkcast necessarily works only on reference operands > on the stack. So ECJ ends up generating bad code for > > import java.lang.annotation.*; > > public class X { > @Target(ElementType.TYPE_USE) > public @interface T { > } > > public static void main(String[] args) { > int i = (@T int) 10; > > } > } > > attempting to emit a checkcast due to the policy of an annotated cast > always being emitted into the classfile. > > (3) JVMS 4.7.20.1 states: > > ... > > type_argument_target { > u2 offset; > u1 type_argument_index; > } > > The value of the offset item specifies the code array offset of either the > bytecode instruction corresponding to the cast expression, the new bytecode > instruction corresponding to the new expression, ... How prescient of JVMS8 4.7.20.1 not to name 'checkcast' as the bytecode instruction corresponding to the cast expression :-) > So what exactly intended to be the value of the offset item for a cast ? > ATM, javac seems to interpret this as the offset of the first > instruction of chunk > of code generated to evaluate the the expression being typecast, while > ECJ makes the offset point to the checkcast instruction itself. If javac implements a cast operator via checkcast (for a reference target type) or {i,l,f,d}2{b,s,i,l,f,d} (for a primitive target type), then that's the answer. If javac does not implement a cast operator at all (usually because the target type is identical to the type of the expression being cast, but also for other reasons: (float)1 doesn't engender a cast from int to float because javac simply emits fconst_1, while a cast to a primitive type is redundant when auto-unboxing occurs), then I recommend that 'offset' indicates the instruction which is responsible for physically pushing on to the stack the value whose type is the target type from the cast operator. For the "(@T int)10" expression above, it would be the ldc that pushes 10. For "(float)1", it would be the fconst_1. For an auto-unbox like "int x = (int)new Integer(1);", it would be the invokevirtual on Integer.intValue(). In effect, I'm recommending the offset of the last instruction of the chunk of code generated to evaluate the expression being cast. However, if javac prefers to record the offset of first instruction, I would not complain. Since there is no compiler spec, this is a quality-of-implementation issue. An implementation which generates bad code for an annotated cast operator is of questionable quality. An implementation which records an annotated cast operator at roughly the right offset is not of questionable quality. Alex From srikanth.adayapalam at oracle.com Fri Dec 11 03:50:06 2015 From: srikanth.adayapalam at oracle.com (Srikanth) Date: Fri, 11 Dec 2015 09:20:06 +0530 Subject: Questions about type annotation on type casts. In-Reply-To: <566A1800.1010104@oracle.com> References: <5668FD3D.5050403@oracle.com> <566A1800.1010104@oracle.com> Message-ID: <566A47EE.7070507@oracle.com> On Friday 11 December 2015 05:55 AM, Alex Buckley wrote: > On 12/9/2015 8:19 PM, Srikanth wrote: >> While working on https://bugs.openjdk.java.net/browse/JDK-8144168, >> a few questions have surfaced regarding code generation for a type >> annotated cast. >> So what exactly intended to be the value of the offset item for a cast ? >> ATM, javac seems to interpret this as the offset of the first >> instruction of chunk >> of code generated to evaluate the the expression being typecast, while >> ECJ makes the offset point to the checkcast instruction itself. > > If javac implements a cast operator via checkcast (for a reference > target type) or {i,l,f,d}2{b,s,i,l,f,d} (for a primitive target type), > then that's the answer. > > If javac does not implement a cast operator at all (usually because > the target type is identical to the type of the expression being cast, Thanks, I think I have the answers to my questions. "... If javac does not implement a cast operator at all (usually because the target type is identical to the type of the expression being cast ..." At first glance, this strategy appears to lead to loss of information, but I presume what is not expressly available can in fact be recovered by analysis of bytecodes. Srikanth From alex.buckley at oracle.com Fri Dec 11 20:21:03 2015 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 11 Dec 2015 12:21:03 -0800 Subject: Questions about type annotation on type casts. In-Reply-To: <566A47EE.7070507@oracle.com> References: <5668FD3D.5050403@oracle.com> <566A1800.1010104@oracle.com> <566A47EE.7070507@oracle.com> Message-ID: <566B302F.1080008@oracle.com> On 12/10/2015 7:50 PM, Srikanth wrote: > On Friday 11 December 2015 05:55 AM, Alex Buckley wrote: >> On 12/9/2015 8:19 PM, Srikanth wrote: >>> While working on https://bugs.openjdk.java.net/browse/JDK-8144168, >>> a few questions have surfaced regarding code generation for a type >>> annotated cast. >>> So what exactly intended to be the value of the offset item for a cast ? >>> ATM, javac seems to interpret this as the offset of the first >>> instruction of chunk >>> of code generated to evaluate the the expression being typecast, while >>> ECJ makes the offset point to the checkcast instruction itself. >> >> If javac implements a cast operator via checkcast (for a reference >> target type) or {i,l,f,d}2{b,s,i,l,f,d} (for a primitive target type), >> then that's the answer. >> >> If javac does not implement a cast operator at all (usually because >> the target type is identical to the type of the expression being cast, > > Thanks, I think I have the answers to my questions. > > "... If javac does not implement a cast operator at all (usually because > the target type is identical to the type of the expression being cast ..." > > At first glance, this strategy appears to lead to loss of information, > but I presume what is not expressly available can in fact be > recovered by analysis of bytecodes. Yes, any analyzer of type annotations in method bodies has to be capable of understanding vendor-specific compiler output. Alex From john.r.rose at oracle.com Fri Dec 11 20:47:37 2015 From: john.r.rose at oracle.com (John Rose) Date: Fri, 11 Dec 2015 12:47:37 -0800 Subject: Questions about type annotation on type casts. In-Reply-To: <566A1800.1010104@oracle.com> References: <5668FD3D.5050403@oracle.com> <566A1800.1010104@oracle.com> Message-ID: <5E729BF9-AB1B-4C7F-ACAC-10EE5108F922@oracle.com> On Dec 10, 2015, at 4:25 PM, Alex Buckley wrote: > > > For the "(@T int)10" expression above, it would be the ldc that pushes 10. For "(float)1", it would be the fconst_1. For an auto-unbox like "int x = (int)new Integer(1);", it would be the invokevirtual on Integer.intValue(). > > In effect, I'm recommending the offset of the last instruction of the chunk of code generated to evaluate the expression being cast. However, if javac prefers to record the offset of first instruction, I would not complain. There is something especially useful about pointing at the bytecode (or one of the bytecodes) that creates the finished expression value (or at least moves it somewhere: astore, areturn, etc). By contrast, some earlier instruction which begins to execute the whole expression is not securely related to the value whose type has been annotated. Loose language about "chunk of code" makes me nervous that we might get dangling annotations. For example, if I annotate the first instruction of the whole expression `(@T int)a[i++]`, the annotation reader will see a logically unrelated operation on `i`. Surely pointing `@T` at `i++` is worse than merely a QOI problem. The meaning of `@T` might be "I know this is an even number", and there's no way to get from the `i` bytecode to see the `a[i++]`, and a reader might erroneously conclude that the programmer is saying `i` is an even number. ? John -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex.buckley at oracle.com Fri Dec 11 21:17:17 2015 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 11 Dec 2015 13:17:17 -0800 Subject: Questions about type annotation on type casts. In-Reply-To: <5E729BF9-AB1B-4C7F-ACAC-10EE5108F922@oracle.com> References: <5668FD3D.5050403@oracle.com> <566A1800.1010104@oracle.com> <5E729BF9-AB1B-4C7F-ACAC-10EE5108F922@oracle.com> Message-ID: <566B3D5D.1050005@oracle.com> On 12/11/2015 12:47 PM, John Rose wrote: > On Dec 10, 2015, at 4:25 PM, Alex Buckley > wrote: >> For the "(@T int)10" expression above, it would be the ldc that pushes >> 10. For "(float)1", it would be the fconst_1. For an auto-unbox like >> "int x = (int)new Integer(1);", it would be the invokevirtual on >> Integer.intValue(). >> >> In effect, I'm recommending the offset of the last instruction of the >> chunk of code generated to evaluate the expression being cast. >> However, if javac prefers to record the offset of first instruction, I >> would not complain. > > There is something especially useful about pointing at the bytecode (or > one of the bytecodes) that creates the finished expression value (or at > least moves it somewhere: astore, areturn, etc). > > By contrast, some earlier instruction which begins to execute the whole > expression is not securely related to the value whose type has been > annotated. Loose language about "chunk of code" makes me nervous that > we might get dangling annotations. > > For example, if I annotate the first instruction of the whole expression > `(@T int)a[i++]`, the annotation reader will see a logically unrelated > operation on `i`. Surely pointing `@T` at `i++` is worse than merely a > QOI problem. The meaning of `@T` might be "I know this is an even > number", and there's no way to get from the `i` bytecode to see the > `a[i++]`, and a reader might erroneously conclude that the programmer is > saying `i` is an even number. Especially since this expression would produce the same bytecode: a[(@T int)i++] This might be a "big" QOI problem, but it's still "just" QOI, since there's no compiler spec which javac is breaking. I suspect that javac "realizes" quite early that it doesn't need an explicit instruction to implement the cast operator; and is aware that the instruction stream for the expression being cast might be complicated; and so is unwilling to hang on to @T throughout the stream's generation; and so gets @T off its plate by recording the most-eager offset, not the most-accurate. If most-accurate would require a major rewrite of some javac phase, then it's probably justified. Srikanth, please advise. Alex From jesse at swank.ca Mon Dec 21 23:47:56 2015 From: jesse at swank.ca (Jesse Wilson) Date: Mon, 21 Dec 2015 23:47:56 +0000 Subject: javac flag to suppress synthetic members? Message-ID: I?m using javac to build libraries that target both Android and desktop Java. Android is particularly sensitive to the size of the compiled classes. But smaller classes improves performance everywhere. I?ve noticed that javac likes to synthesize additional members to build visibility trampolines for nested classes. In the compiled code for OkHttp , nearly 10% of the method references are synthetic! I?m tempted to create a classfile rewriter to remove these synthetic members. It?d have to promote some private things to package-private to make the synthetic things unnecessary. One alternative to classfile magic would be a new javac flag like --avoid-synthetic-members. Such a flag would change private members to package-private when those members were accessed by nested classes. The compiled code would be smaller, run faster, and have less weird garbage in the stack traces. Are javac maintainers receptive to a patch that adds such a flag? What?s the process of turning this proposal into a feature? Thanks. Jesse Wilson ? -------------- next part -------------- An HTML attachment was scrubbed... URL: From jonathan.gibbons at oracle.com Mon Dec 21 23:53:37 2015 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Mon, 21 Dec 2015 15:53:37 -0800 Subject: javac flag to suppress synthetic members? In-Reply-To: References: Message-ID: <56789101.9090409@oracle.com> A version of javac that translates source files into class files that don't match the original source sounds very suspect to me. -- Jon On 12/21/2015 03:47 PM, Jesse Wilson wrote: > > I?m using javac to build libraries that target both Android and > desktop Java. Android is particularly sensitive to the size of the > compiled classes. But smaller classes improves performance everywhere. > > I?ve noticed that javac likes to synthesize additional members to > build visibility trampolines for nested classes. In the compiled code > for OkHttp , nearly 10% of the > method references are synthetic! > > I?m tempted to create a classfile rewriter to remove these synthetic > members. It?d have to promote some |private| things to > |package-private| to make the synthetic things unnecessary. > > One alternative to classfile magic would be a new javac flag like > |--avoid-synthetic-members|. Such a flag would change |private| > members to |package-private| when those members were accessed by > nested classes. The compiled code would be smaller, run faster, and > have less weird garbage in the stack traces. > > Are javac maintainers receptive to a patch that adds such a flag? > What?s the process of turning this proposal into a feature? > > Thanks. > Jesse Wilson > > ? -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Tue Dec 22 00:00:40 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 22 Dec 2015 00:00:40 +0000 Subject: javac flag to suppress synthetic members? In-Reply-To: References: Message-ID: <567892A8.6090908@oracle.com> Hi Jesse, I understand where you are coming from, but I guess I question your numbers a little bit :-) It is true that javac (and all javac compilers, really) emit lots of synthetics nowadays - those are used for a number of reasons: 1) accessibility for otherwise inaccessible members in inner classes 2) erasure bridges 3) visibility bridges (*) 4) lambda translation methods ... Of these, the only ones that could be considered redundant are those in (3) - provided you don't care about runtime reflection. Disabling synthetics for all the others will result in significant semantics change (lambdas are the extreme case - if you drop the synthetic, your lambda body goes away and the code won't even link!). I believe what you want is to tweak the source code so as to minimize generation of those synthetic methods (which you have done already - to some degree). If you stick with public members and avoid use of generics when overriding methods, I think you would have reduced the need of the most common sources for synthetic methods. If you want to make this more 'official' you can even write an annotation processor or - better, a compiler plugin [1], to enforce the rules that you think are providing the best results under your circumstances. I think adding a compiler switch is addressing the problem at the wrong level. However, if you find cases where the compiler is obviously emitting redundant synthetic methods - please do let us know - as these will need to be treated as bugs. [1] - https://docs.oracle.com/javase/8/docs/jdk/api/javac/tree/com/sun/source/util/Plugin.html Maurizio On 21/12/15 23:47, Jesse Wilson wrote: > > I?m using javac to build libraries that target both Android and > desktop Java. Android is particularly sensitive to the size of the > compiled classes. But smaller classes improves performance everywhere. > > I?ve noticed that javac likes to synthesize additional members to > build visibility trampolines for nested classes. In the compiled code > for OkHttp , nearly 10% of the > method references are synthetic! > > I?m tempted to create a classfile rewriter to remove these synthetic > members. It?d have to promote some |private| things to > |package-private| to make the synthetic things unnecessary. > > One alternative to classfile magic would be a new javac flag like > |--avoid-synthetic-members|. Such a flag would change |private| > members to |package-private| when those members were accessed by > nested classes. The compiled code would be smaller, run faster, and > have less weird garbage in the stack traces. > > Are javac maintainers receptive to a patch that adds such a flag? > What?s the process of turning this proposal into a feature? > > Thanks. > Jesse Wilson > > ? -------------- next part -------------- An HTML attachment was scrubbed... URL: From jakewharton at gmail.com Tue Dec 22 03:40:54 2015 From: jakewharton at gmail.com (Jake Wharton) Date: Tue, 22 Dec 2015 03:40:54 +0000 Subject: javac flag to suppress synthetic members? Message-ID: javac is already rewriting the callsite to point at a completely different method than the source indicates, and one that's not even present anywhere in the original source file. In a strictly objective look at the javac's rewriting behavior, the proposal is far less drastic in terms of changes to the generated code than the current behavior. -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Tue Dec 22 11:21:59 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 22 Dec 2015 11:21:59 +0000 Subject: javac flag to suppress synthetic members? In-Reply-To: References: Message-ID: <56793257.7090906@oracle.com> On 22/12/15 03:40, Jake Wharton wrote: > javac is already rewriting the callsite to point at a completely > different method than the source indicates, and one that's not even > present anywhere in the original source file. In a strictly objective > look at the javac's rewriting behavior, the proposal is far less > drastic in terms of changes to the generated code than the current > behavior. This is true for any synthetic code generation right? I.e. when the compiler emits synthetic code, a new discrepancy is added between source and classfile. But I think we also have to look under the lid and ask - why does this code end up here? In the case of accessor methods, without them it would be impossible to call non-public members of an enclosing class - which is something that the language allows you to do (and the VM doesn't, given the VM doesn't have a true notion of inner classes). In cases like these resorting to synthetic code is unavoidable, and dropping synthetic members will mean changing the language. I still think that the idea I proposed (add extra static checks to enforce the rules you find useful, e.g. "no lambdas, no private access to enclosing classes, ....") might lead to a better outcome, since you'll be taming the beast at the right level - i.e. by deliberately restricting yourself not to use those features which cause too much synthetic code bloat. Maurizio -------------- next part -------------- An HTML attachment was scrubbed... URL: