From alex.buckley at oracle.com Mon Feb 1 18:44:52 2016 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 01 Feb 2016 10:44:52 -0800 Subject: Bug in encoding type annotations for supertype_targets In-Reply-To: References: <56AA6D95.1040200@oracle.com> <56AA762F.1050800@oracle.com> Message-ID: <56AFA7A4.70403@oracle.com> Yes, the reason I explicitly confirmed that the "Outer . @Foo Inner" terms were legal in source is because static nested types are in play, and they have tricky rules about what can be annotated and what can't. As you indicate, "@Foo Outer . Inner" would be illegal in source. I don't understand why you say this is a reflection issue when javac is consistently failing to emit the target_path item for annotated static nested types. Presumably javac is treating "@Foo Inner" as not-nested-in-Outer, but that's wrong from a class file and j.l.r.AnnotatedType point of view. Alex On 1/31/2016 8:37 AM, Joel Borggr?n-Franck wrote: > So when debugging this in javac I realized I'm probably wrong, and > this looks like a reflection issue once again. > > In both "erroneous" cases above the class or the interface is > statically nested, so there is only one type where the annotation can > appear (the innermost type). I checked a similar case on fields, > > public class Outer { > public static class Inner { > Outer . @TA Outer foo; > } > } > > and javac omits the type_path here as well. I'm not sure this was a > conscious choice, but due to how javac treats statically nested > classes I think this will be consistent across the board. This means > I'll have to sort out the nesting on the reflective side. > > What do you think? > > cheers > /Joel > > On Thu, Jan 28, 2016 at 9:12 PM, Alex Buckley wrote: >> Yes, we are agreeing that i) target_info (in particular, the >> supertype_target variant) is likely emitted correctly, and ii) target_path >> is not. >> >> It also seems that javap is printing "type_index=..." for the target_info >> item (not target_path as I said before). >> >> Alex >> >> >> On 1/28/2016 12:05 PM, Joel Borggr?n-Franck wrote: >>> >>> Hi Alex, >>> >>> Actually I suspect the target_info is correct, a supertype_target with >>> a supertype_index of 65535 for the class cases but read into a signed >>> char, and 0 for the 0:th interface. This isn't the type_index entry >>> later in type_annotation structure, Javap just has a non-standard >>> notation (another bug perhaps?) >>> >>> Created: https://bugs.openjdk.java.net/browse/JDK-8148504 >>> >>> cheers >>> /Joel >>> >>> On Thu, Jan 28, 2016 at 8:35 PM, Alex Buckley >>> wrote: >>>> >>>> Hi Joel, >>>> >>>> On 1/28/2016 10:45 AM, Joel Borggr?n-Franck wrote: >>>>> >>>>> >>>>> While working on the core reflection code for type annotation I >>>>> discovered what I believe is a javac bug. It looks like javac omits >>>>> the type_path structure for nested types in supertype and implemets >>>>> targets. In the example below, when looking at GenericSub in javap I >>>>> get this encoding of @Foo: >>>>> >>>>> RuntimeVisibleTypeAnnotations: >>>>> 0: #18(): CLASS_EXTENDS, type_index=-1, location=[TYPE_ARGUMENT(0)] >>>>> >>>>> as expected, but when looking at either Impl or SubInner I get: >>>>> >>>>> RuntimeVisibleTypeAnnotations: >>>>> 0: #15(): CLASS_EXTENDS, type_index=0 >>>>> >>>>> or >>>>> >>>>> RuntimeVisibleTypeAnnotations: >>>>> 0: #14(): CLASS_EXTENDS, type_index=-1 >>>>> >>>>> Note the missing type_path (location in javap) for the nesting, which >>>>> I think table Table 4.7.20.2-E in the vm spec implies. >>>>> >>>>> I can file a bug if you want me to. >>>> >>>> >>>> >>>> I agree that the "Outer . @Foo Inner"-style terms are legal, and should >>>> have >>>> a target_path item generated. >>>> >>>> To be precise, the supertype_target item belongs to the target_info item, >>>> not the target_path item. supertype_target encodes which type is of >>>> interest >>>> among the one or more types specified after 'extends'/'implements'. All >>>> your >>>> sample programs have exactly one type in their 'extends'/'implements' >>>> clauses, so I'd be fairly confident that supertype_target is correct. >>>> What >>>> is more likely to be wrong is (as you say) the target_path item which >>>> encodes the "structural" location of a type annotation within a >>>> nested/parameterized/array type. >>>> >>>> The type_index items are surprising too. type_index is not about the >>>> location of a type annotation, but about the annotation itself ("@Foo"). >>>> It >>>> encodes the constant pool entry which gives the annotation's own type. 0 >>>> and >>>> -1 are bad answers for that. I suspect javap is actually finding >>>> target_path >>>> items (possibly ill-formed) and showing them as type_index. >>>> >>>> So yes, please file a bug. >>>> >>>> Alex >>>> >>>> >>>>> cheers >>>>> /Joel >>>>> >>>>> --- 8< --- >>>>> >>>>> import java.lang.annotation.*; >>>>> import java.util.*; >>>>> import java.lang.reflect.*; >>>>> >>>>> /* >>>>> * @test >>>>> */ >>>>> public class LostTypePath {} >>>>> >>>>> class Super {} >>>>> class Sub extends @Foo Super {} >>>>> >>>>> class Generic {} >>>>> class GenericSub extends Generic<@Foo B> {} >>>>> >>>>> class Outer { public static class Inner {}} >>>>> class SubInner extends Outer . @Foo Inner {} >>>>> >>>>> interface IOuter { public interface IInner {}} >>>>> class Impl implements IOuter . @Foo IInner {} >>>>> >>>>> @Target(ElementType.TYPE_USE) >>>>> @Retention(RetentionPolicy.RUNTIME) >>>>> @interface Foo {} >>>>> >>>> >> From joel.borggren.franck at gmail.com Tue Feb 2 20:01:52 2016 From: joel.borggren.franck at gmail.com (=?UTF-8?Q?Joel_Borggr=C3=A9n=2DFranck?=) Date: Tue, 2 Feb 2016 21:01:52 +0100 Subject: Bug in encoding type annotations for supertype_targets In-Reply-To: <56AFA7A4.70403@oracle.com> References: <56AA6D95.1040200@oracle.com> <56AA762F.1050800@oracle.com> <56AFA7A4.70403@oracle.com> Message-ID: Hi Alex, On Mon, Feb 1, 2016 at 7:44 PM, Alex Buckley wrote: > Yes, the reason I explicitly confirmed that the "Outer . @Foo Inner" terms > were legal in source is because static nested types are in play, and they > have tricky rules about what can be annotated and what can't. As you > indicate, "@Foo Outer . Inner" would be illegal in source. > > I don't understand why you say this is a reflection issue when javac is > consistently failing to emit the target_path item for annotated static > nested types. Presumably javac is treating "@Foo Inner" as > not-nested-in-Outer, but that's wrong from a class file and > j.l.r.AnnotatedType point of view. Only because in my experience this is how we usually did it. When the spec and the compiler disagrees, the compiler usually wins. I think encoding statically nested classes without a target_path is technically viable since there is only one type that can be annotated, thus core reflection can sort it out, even if it is complicated. However given that type annotations never really worked perhaps it is better to just fix the compiler in 9, which IMO is a better choice if we can sidestep the compatibility issue. cheers /Joel From alex.buckley at oracle.com Tue Feb 2 20:06:44 2016 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 02 Feb 2016 12:06:44 -0800 Subject: Bug in encoding type annotations for supertype_targets In-Reply-To: References: <56AA6D95.1040200@oracle.com> <56AA762F.1050800@oracle.com> <56AFA7A4.70403@oracle.com> Message-ID: <56B10C54.8060504@oracle.com> Hi Joel, On 2/2/2016 12:01 PM, Joel Borggr?n-Franck wrote: > On Mon, Feb 1, 2016 at 7:44 PM, Alex Buckley wrote: >> Yes, the reason I explicitly confirmed that the "Outer . @Foo Inner" terms >> were legal in source is because static nested types are in play, and they >> have tricky rules about what can be annotated and what can't. As you >> indicate, "@Foo Outer . Inner" would be illegal in source. >> >> I don't understand why you say this is a reflection issue when javac is >> consistently failing to emit the target_path item for annotated static >> nested types. Presumably javac is treating "@Foo Inner" as >> not-nested-in-Outer, but that's wrong from a class file and >> j.l.r.AnnotatedType point of view. > > Only because in my experience this is how we usually did it. When the > spec and the compiler disagrees, the compiler usually wins. I think > encoding statically nested classes without a target_path is > technically viable since there is only one type that can be annotated, > thus core reflection can sort it out, even if it is complicated. > > However given that type annotations never really worked perhaps it is > better to just fix the compiler in 9, which IMO is a better choice if > we can sidestep the compatibility issue. Absolutely agree that it's best to fix javac (rather than Core Reflection) in JDK 9. Alex From cushon at google.com Wed Feb 3 18:41:40 2016 From: cushon at google.com (Liam Miller-Cushon) Date: Wed, 3 Feb 2016 10:41:40 -0800 Subject: More type inference changes Message-ID: I noticed three more javac9 type inference incompatibilities, each of which only occurs once in the codebase I've been testing against. 1) The following code is rejected by javac9 at head, and accepted by earlier versions. The first bad revision is 3211. http://hg.openjdk.java.net/jdk9/dev/langtools/rev/3211 http://bugs.openjdk.java.net/browse/JDK-8147493 abstract class Test { interface O {} interface R {} interface S { S t(C x); } abstract D a(Class methodCall); abstract R g(O q, String s); abstract S w(E m); S> f(R r) { return w(g(a(O.class), a(String.class))).t(r); } } error: incompatible types: S cannot be converted to S> return w(g(a(O.class), a(String.class))).t(r); ^ 2) This is also rejected at head, and accepted by earlier versions. The first bad revision is 3030. http://hg.openjdk.java.net/jdk9/dev/langtools/rev/3030 http://bugs.openjdk.java.net/browse/JDK-8078093 abstract class Test { interface One {} interface Two {} interface Three {} interface Four {} abstract One h(Class clazz); abstract void g(One> x); void f() { g(h(Two.class)); } } error: incompatible types: One cannot be converted to One> g(h(Two.class)); ^ 3) This one is accepted at head, and also by earlier versions. It was briefly rejected between 3030 and 3109. Was the fix in 3109 deliberate? First bad revision: http://hg.openjdk.java.net/jdk9/dev/langtools/rev/3030 https://bugs.openjdk.java.net/browse/JDK-8078093 First good revision: http://hg.openjdk.java.net/jdk9/dev/langtools/rev/3109 http://bugs.openjdk.java.net/browse/JDK-8067767 abstract class Test { interface One> {} abstract > void g(One f); abstract One h(); void f() { g(h()); } } error: method g in class Test cannot be applied to given types; g(h()); ^ required: One found: One reason: inferred type does not conform to upper bound(s) inferred: E#2 upper bound(s): One,One> where D,E#1,E#2, are type-variables: D extends Object declared in method g(One) E#1 extends One declared in method g(One) E#2 extends One> extends One where CAP#1 is a fresh type-variable: CAP#1 extends One from capture of ? -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Wed Feb 3 21:54:34 2016 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 3 Feb 2016 21:54:34 +0000 Subject: More type inference changes In-Reply-To: References: Message-ID: <56B2771A.4030708@oracle.com> Adding Dan On 03/02/16 18:41, Liam Miller-Cushon wrote: > I noticed three more javac9 type inference incompatibilities, each of > which only occurs once in the codebase I've been testing against. > > 1) The following code is rejected by javac9 at head, and accepted by > earlier versions. The first bad revision is 3211. > > http://hg.openjdk.java.net/jdk9/dev/langtools/rev/3211 > http://bugs.openjdk.java.net/browse/JDK-8147493 > > abstract class Test { > > interface O {} > interface R {} > interface S { S t(C x); } > abstract D a(Class methodCall); > abstract R g(O q, String s); > abstract S w(E m); > > S> f(R r) { > return w(g(a(O.class), a(String.class))).t(r); > } > } > > error: incompatible types: S cannot be converted to S> > return w(g(a(O.class), a(String.class))).t(r); This looks ok to me? I.e. the call to 'a' with O.class is fine (not unchecked) - but the next call to 'g' is unchecked, as the return type for 'a' is simply O and the target type is O - that triggers the unchecked call and that means that the return type of 'g' is erased to R, and then the inference variable of 'w' (E) is inferred as R, meaning that the return type is S - which means the signature of 't' inside S is (R)S, so indeed the return type of that method (S) seems not compatible with the return type of your 'f' (S>). Would you agree? > ^ > > 2) This is also rejected at head, and accepted by earlier versions. > The first bad revision is 3030. > > http://hg.openjdk.java.net/jdk9/dev/langtools/rev/3030 > http://bugs.openjdk.java.net/browse/JDK-8078093 > > abstract class Test { > > interface One {} > interface Two {} > interface Three {} > interface Four {} > abstract One h(Class clazz); > abstract void g(One> x); > > void f() { > g(h(Two.class)); > } > } > > error: incompatible types: One cannot be converted to One extends Two> > g(h(Two.class)); > ^ On this one, I'm also not sure: h(Two.class) means that D is inferred as the raw Two. So 'h' returns One. Is One compatible with One> ? This essentially means asking as to whether Two <: Two Since containment use strict subtyping, and not unchecked, I think this means that this is not compatible? [For what it's worth, Eclipse agrees on this one] > > > 3) This one is accepted at head, and also by earlier versions. It was > briefly rejected between 3030 and 3109. Was the fix in 3109 deliberate? I don't think it was deliberate to change this (in both changesets), so I will need to study the inference graphs before/after; Eclipse hangs (at least the version I tried to use) when compiling this. It seems like this should pass - an extra synthetic inference variable should be introduced for the wildcard, so that it's One <: One, which means: A == D U == E and they are all inferred as Object. Maurizio > > First bad revision: > http://hg.openjdk.java.net/jdk9/dev/langtools/rev/3030 > https://bugs.openjdk.java.net/browse/JDK-8078093 > > First good revision: > http://hg.openjdk.java.net/jdk9/dev/langtools/rev/3109 > http://bugs.openjdk.java.net/browse/JDK-8067767 > > abstract class Test { > > interface One> {} > abstract > void g(One f); > abstract One h(); > > void f() { > g(h()); > } > } > > error: method g in class Test cannot be applied to given types; > g(h()); > ^ > required: One > found: One > reason: inferred type does not conform to upper bound(s) > inferred: E#2 > upper bound(s): One,One> > where D,E#1,E#2, are type-variables: > D extends Object declared in method g(One) > E#1 extends One declared in method g(One) > E#2 extends One> > extends One > where CAP#1 is a fresh type-variable: > CAP#1 extends One from capture of ? > From cushon at google.com Thu Feb 4 01:49:59 2016 From: cushon at google.com (Liam Miller-Cushon) Date: Wed, 3 Feb 2016 17:49:59 -0800 Subject: More type inference changes In-Reply-To: <56B2771A.4030708@oracle.com> References: <56B2771A.4030708@oracle.com> Message-ID: On Wed, Feb 3, 2016 at 1:54 PM, Maurizio Cimadamore < maurizio.cimadamore at oracle.com> wrote: > > This looks ok to me? > > I.e. the call to 'a' with O.class is fine (not unchecked) - but the next > call to 'g' is unchecked, as the return type for 'a' is simply O and the > target type is O - that triggers the unchecked call and that means > that the return type of 'g' is erased to R, and then the inference variable > of 'w' (E) is inferred as R, meaning that the return type is S - which > means the signature of 't' inside S is (R)S, so indeed the return > type of that method (S) seems not compatible with the return type of > your 'f' (S>). Would you agree? That makes sense, when I was looking at it earlier I missed that the call to 'w' is not unchecked. Thanks for investigating. I wasn't sure if these were bugs or enhancements. I was mostly hoping to get confirmation either way, and I figured they might be useful as tests. -------------- next part -------------- An HTML attachment was scrubbed... URL: From cushon at google.com Thu Feb 4 19:57:56 2016 From: cushon at google.com (Liam Miller-Cushon) Date: Thu, 4 Feb 2016 11:57:56 -0800 Subject: RFR: Use StringJoiner in sjavac options handling Message-ID: Some benchmarking showed that sjavac's option handling is spending a lot of time on string concatenation. Any interest in taking this trivial fix? # HG changeset patch # User Liam Miller-Cushon # Date 1454615087 28800 # Thu Feb 04 11:44:47 2016 -0800 # Node ID dea4ee331c161ffda376b1a91f84c4e905f0d0fe # Parent 873c5cde4f08f6fffe02cd1f2877111783797be7 Use StringJoiner in sjavac options handling diff -r 873c5cde4f08 -r dea4ee331c16 src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java --- a/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java Tue Feb 02 16:11:09 2016 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java Thu Feb 04 11:44:47 2016 -0800 @@ -33,6 +33,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.StringJoiner; import java.util.HashSet; import com.sun.tools.sjavac.Transformer; @@ -225,10 +226,7 @@ } String getResult() { - String result = ""; - for (String s : args) - result += s + " "; - return result.trim(); + return String.join(" ", args); } public void addAll(Collection toAdd) { @@ -337,10 +335,11 @@ // Helper method to join a list of source locations separated by // File.pathSeparator private static String concatenateSourceLocations(List locs) { - String s = ""; - for (SourceLocation loc : locs) - s += (s.isEmpty() ? "" : java.io.File.pathSeparator) + loc.getPath(); - return s; + StringJoiner joiner = new StringJoiner(java.io.File.pathSeparator); + for (SourceLocation loc : locs) { + joiner.add(loc.getPath().toString()); + } + return joiner.toString(); } // OptionHelper that records the traversed options in this Options instance. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jonathan.gibbons at oracle.com Thu Feb 4 21:14:53 2016 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Thu, 04 Feb 2016 13:14:53 -0800 Subject: RFR: Use StringJoiner in sjavac options handling In-Reply-To: References: Message-ID: <56B3BF4D.9090004@oracle.com> Looks sensible to me. -- Jon On 02/04/2016 11:57 AM, Liam Miller-Cushon wrote: > Some benchmarking showed that sjavac's option handling is spending a > lot of time on string concatenation. Any interest in taking this > trivial fix? > > # HG changeset patch > # User Liam Miller-Cushon > > # Date 1454615087 28800 > # Thu Feb 04 11:44:47 2016 -0800 > # Node ID dea4ee331c161ffda376b1a91f84c4e905f0d0fe > # Parent 873c5cde4f08f6fffe02cd1f2877111783797be7 > Use StringJoiner in sjavac options handling > > diff -r 873c5cde4f08 -r dea4ee331c16 > src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java > --- > a/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.javaTue > Feb 02 16:11:09 2016 -0800 > +++ > b/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.javaThu > Feb 04 11:44:47 2016 -0800 > @@ -33,6 +33,7 @@ > import java.util.List; > import java.util.Map; > import java.util.Set; > +import java.util.StringJoiner; > import java.util.HashSet; > import com.sun.tools.sjavac.Transformer; > @@ -225,10 +226,7 @@ > } > String getResult() { > - String result = ""; > - for (String s : args) > - result += s + " "; > - return result.trim(); > + return String.join(" ", args); > } > public void addAll(Collection toAdd) { > @@ -337,10 +335,11 @@ > // Helper method to join a list of source locations separated by > // File.pathSeparator > private static String > concatenateSourceLocations(List locs) { > - String s = ""; > - for (SourceLocation loc : locs) > - s += (s.isEmpty() ? "" : java.io.File.pathSeparator) + > loc.getPath(); > - return s; > + StringJoiner joiner = new > StringJoiner(java.io.File.pathSeparator); > + for (SourceLocation loc : locs) { > + joiner.add(loc.getPath().toString()); > + } > + return joiner.toString(); > } > // OptionHelper that records the traversed options in this > Options instance. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jonathan.gibbons at oracle.com Fri Feb 5 21:58:33 2016 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Fri, 05 Feb 2016 13:58:33 -0800 Subject: RFR: Use StringJoiner in sjavac options handling In-Reply-To: References: Message-ID: <56B51B09.5080107@oracle.com> https://bugs.openjdk.java.net/browse/JDK-8149160 -- Jon On 02/04/2016 11:57 AM, Liam Miller-Cushon wrote: > Some benchmarking showed that sjavac's option handling is spending a > lot of time on string concatenation. Any interest in taking this > trivial fix? > > # HG changeset patch > # User Liam Miller-Cushon > > # Date 1454615087 28800 > # Thu Feb 04 11:44:47 2016 -0800 > # Node ID dea4ee331c161ffda376b1a91f84c4e905f0d0fe > # Parent 873c5cde4f08f6fffe02cd1f2877111783797be7 > Use StringJoiner in sjavac options handling > > diff -r 873c5cde4f08 -r dea4ee331c16 > src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java > --- > a/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.javaTue > Feb 02 16:11:09 2016 -0800 > +++ > b/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.javaThu > Feb 04 11:44:47 2016 -0800 > @@ -33,6 +33,7 @@ > import java.util.List; > import java.util.Map; > import java.util.Set; > +import java.util.StringJoiner; > import java.util.HashSet; > import com.sun.tools.sjavac.Transformer; > @@ -225,10 +226,7 @@ > } > String getResult() { > - String result = ""; > - for (String s : args) > - result += s + " "; > - return result.trim(); > + return String.join(" ", args); > } > public void addAll(Collection toAdd) { > @@ -337,10 +335,11 @@ > // Helper method to join a list of source locations separated by > // File.pathSeparator > private static String > concatenateSourceLocations(List locs) { > - String s = ""; > - for (SourceLocation loc : locs) > - s += (s.isEmpty() ? "" : java.io.File.pathSeparator) + > loc.getPath(); > - return s; > + StringJoiner joiner = new > StringJoiner(java.io.File.pathSeparator); > + for (SourceLocation loc : locs) { > + joiner.add(loc.getPath().toString()); > + } > + return joiner.toString(); > } > // OptionHelper that records the traversed options in this > Options instance. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From gunnar at hibernate.org Mon Feb 8 16:16:34 2016 From: gunnar at hibernate.org (Gunnar Morling) Date: Mon, 8 Feb 2016 17:16:34 +0100 Subject: [Jigsaw] Getting "Bad service configuration file" error with annotation processor Message-ID: Hi, I'm looking into building one of the Hibernate projects, Hibernate Validator, using the Jigsaw-enabled early access build 104. The build uses an annotation processor, which causes the following error: "Bad service configuration file, or exception thrown while constructing Processor object: javax.annotation.processing.Processor: Provider org.jboss.logging.processor.apt.LoggingToolsProcessor could not be instantiated" The the processor is added via the "-processormodulepath" option. Unfortunately, javac doesn't provide any further context information other than this short error. I tried adding "-verbose" to the javac invocation, but that didn't give me any further information. I also tried to invoke the processor programmatically using the JSR 199 compiler API, but that resulted in a NoClassDefFoundError: javax/tools/DiagnosticListener. The processor works as expected with the non-Jigsaw build 104. Does anyone have an idea of what I could do to to reveal what's the problem here? Thanks, --Gunnar From jonathan.gibbons at oracle.com Mon Feb 8 17:07:50 2016 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Mon, 08 Feb 2016 09:07:50 -0800 Subject: [Jigsaw] Getting "Bad service configuration file" error with annotation processor In-Reply-To: References: Message-ID: <56B8CB66.5030008@oracle.com> Gunnar, cross-posting to jigsaw-dev. Can you describe more about the setup of this example? Is the processor in a module with a module declaration with a provides clause for the processor, or is it a "pre-Jigsaw"/"JDK8-style" processor with a service configuration file in a jar file's META-INF directory? If it's "old-style" you should be able to use -processorpath, as before. -- Jon On 02/08/2016 08:16 AM, Gunnar Morling wrote: > Hi, > > I'm looking into building one of the Hibernate projects, Hibernate > Validator, using the Jigsaw-enabled early access build 104. > > The build uses an annotation processor, which causes the following error: > > "Bad service configuration file, or exception thrown while > constructing Processor object: javax.annotation.processing.Processor: > Provider org.jboss.logging.processor.apt.LoggingToolsProcessor could > not be instantiated" > > The the processor is added via the "-processormodulepath" option. > Unfortunately, javac doesn't provide any further context information > other than this short error. > > I tried adding "-verbose" to the javac invocation, but that didn't > give me any further information. I also tried to invoke the processor > programmatically using the JSR 199 compiler API, but that resulted in > a NoClassDefFoundError: javax/tools/DiagnosticListener. > > The processor works as expected with the non-Jigsaw build 104. > > Does anyone have an idea of what I could do to to reveal what's the > problem here? > > Thanks, > > --Gunnar From vicente.romero at oracle.com Mon Feb 8 18:38:49 2016 From: vicente.romero at oracle.com (Vicente-Arturo Romero-Zaldivar) Date: Mon, 8 Feb 2016 10:38:49 -0800 Subject: [Jigsaw] Getting "Bad service configuration file" error with annotation processor In-Reply-To: References: Message-ID: <56B8E0B9.6040408@oracle.com> Hi Gunnar, Thanks for the report and sorry to hear that you are experiencing this issue. Could you please send us a reduced version of the failing annotation processor that reproduces the issue? Thanks, Vicente On 02/08/2016 08:16 AM, Gunnar Morling wrote: > Hi, > > I'm looking into building one of the Hibernate projects, Hibernate > Validator, using the Jigsaw-enabled early access build 104. > > The build uses an annotation processor, which causes the following error: > > "Bad service configuration file, or exception thrown while > constructing Processor object: javax.annotation.processing.Processor: > Provider org.jboss.logging.processor.apt.LoggingToolsProcessor could > not be instantiated" > > The the processor is added via the "-processormodulepath" option. > Unfortunately, javac doesn't provide any further context information > other than this short error. > > I tried adding "-verbose" to the javac invocation, but that didn't > give me any further information. I also tried to invoke the processor > programmatically using the JSR 199 compiler API, but that resulted in > a NoClassDefFoundError: javax/tools/DiagnosticListener. > > The processor works as expected with the non-Jigsaw build 104. > > Does anyone have an idea of what I could do to to reveal what's the > problem here? > > Thanks, > > --Gunnar From alex.buckley at oracle.com Mon Feb 8 19:30:09 2016 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 08 Feb 2016 11:30:09 -0800 Subject: [Jigsaw] Getting "Bad service configuration file" error with annotation processor In-Reply-To: <56B8CB66.5030008@oracle.com> References: <56B8CB66.5030008@oracle.com> Message-ID: <56B8ECC1.2080507@oracle.com> The NoClassDefFoundError for javax.tools.DiagnosticListener makes me suspect that the project's code is in the unnamed module (a.k.a. on the classpath) and that no other module has read the java.compiler module which exports the javax.tools package. Hence, java.compiler is not in the module graph. java.compiler also exports the javax.annotation.processing package, so this would explain the inability to instantiate the service provider class -- the service interface type javax.annotation.processing.Processor is not visible. To ensure the java.compiler module is in the module graph, specify -addmods java.compiler on the command line. Alex On 2/8/2016 9:07 AM, Jonathan Gibbons wrote: > Gunnar, > > cross-posting to jigsaw-dev. > > Can you describe more about the setup of this example? Is the processor > in a module with a module declaration with a provides clause for the > processor, or is it a "pre-Jigsaw"/"JDK8-style" processor with a service > configuration file in a jar file's META-INF directory? > > If it's "old-style" you should be able to use -processorpath, as before. > > -- Jon > > > On 02/08/2016 08:16 AM, Gunnar Morling wrote: >> Hi, >> >> I'm looking into building one of the Hibernate projects, Hibernate >> Validator, using the Jigsaw-enabled early access build 104. >> >> The build uses an annotation processor, which causes the following error: >> >> "Bad service configuration file, or exception thrown while >> constructing Processor object: javax.annotation.processing.Processor: >> Provider org.jboss.logging.processor.apt.LoggingToolsProcessor could >> not be instantiated" >> >> The the processor is added via the "-processormodulepath" option. >> Unfortunately, javac doesn't provide any further context information >> other than this short error. >> >> I tried adding "-verbose" to the javac invocation, but that didn't >> give me any further information. I also tried to invoke the processor >> programmatically using the JSR 199 compiler API, but that resulted in >> a NoClassDefFoundError: javax/tools/DiagnosticListener. >> >> The processor works as expected with the non-Jigsaw build 104. >> >> Does anyone have an idea of what I could do to to reveal what's the >> problem here? >> >> Thanks, >> >> --Gunnar > From andreas.lundblad at oracle.com Mon Feb 8 21:43:50 2016 From: andreas.lundblad at oracle.com (Andreas Lundblad) Date: Mon, 8 Feb 2016 22:43:50 +0100 Subject: RFR: Use StringJoiner in sjavac options handling In-Reply-To: References: Message-ID: <20160208214350.GA14695@e6430> On Thu, Feb 04, 2016 at 11:57:56AM -0800, Liam Miller-Cushon wrote: > Some benchmarking showed that sjavac's option handling is spending a lot of > time on string concatenation. Any interest in taking this trivial fix? Sorry for late reply. Change looks great. Will you push it or should I? -- Andreas > # HG changeset patch > # User Liam Miller-Cushon > # Date 1454615087 28800 > # Thu Feb 04 11:44:47 2016 -0800 > # Node ID dea4ee331c161ffda376b1a91f84c4e905f0d0fe > # Parent 873c5cde4f08f6fffe02cd1f2877111783797be7 > Use StringJoiner in sjavac options handling > > diff -r 873c5cde4f08 -r dea4ee331c16 > src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java > --- > a/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java Tue > Feb 02 16:11:09 2016 -0800 > +++ > b/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java Thu > Feb 04 11:44:47 2016 -0800 > @@ -33,6 +33,7 @@ > import java.util.List; > import java.util.Map; > import java.util.Set; > +import java.util.StringJoiner; > import java.util.HashSet; > > import com.sun.tools.sjavac.Transformer; > @@ -225,10 +226,7 @@ > } > > String getResult() { > - String result = ""; > - for (String s : args) > - result += s + " "; > - return result.trim(); > + return String.join(" ", args); > } > > public void addAll(Collection toAdd) { > @@ -337,10 +335,11 @@ > // Helper method to join a list of source locations separated by > // File.pathSeparator > private static String concatenateSourceLocations(List > locs) { > - String s = ""; > - for (SourceLocation loc : locs) > - s += (s.isEmpty() ? "" : java.io.File.pathSeparator) + > loc.getPath(); > - return s; > + StringJoiner joiner = new StringJoiner(java.io.File.pathSeparator); > + for (SourceLocation loc : locs) { > + joiner.add(loc.getPath().toString()); > + } > + return joiner.toString(); > } > > // OptionHelper that records the traversed options in this Options > instance. From jonathan.gibbons at oracle.com Mon Feb 8 22:28:01 2016 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Mon, 08 Feb 2016 14:28:01 -0800 Subject: RFR: Use StringJoiner in sjavac options handling In-Reply-To: <20160208214350.GA14695@e6430> References: <20160208214350.GA14695@e6430> Message-ID: <56B91671.8020906@oracle.com> I was hoping you would, but if you'd prefer me to do it, I can. -- Jon On 02/08/2016 01:43 PM, Andreas Lundblad wrote: > On Thu, Feb 04, 2016 at 11:57:56AM -0800, Liam Miller-Cushon wrote: >> Some benchmarking showed that sjavac's option handling is spending a lot of >> time on string concatenation. Any interest in taking this trivial fix? > Sorry for late reply. Change looks great. > > Will you push it or should I? > > -- Andreas > > > >> # HG changeset patch >> # User Liam Miller-Cushon >> # Date 1454615087 28800 >> # Thu Feb 04 11:44:47 2016 -0800 >> # Node ID dea4ee331c161ffda376b1a91f84c4e905f0d0fe >> # Parent 873c5cde4f08f6fffe02cd1f2877111783797be7 >> Use StringJoiner in sjavac options handling >> >> diff -r 873c5cde4f08 -r dea4ee331c16 >> src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java >> --- >> a/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java Tue >> Feb 02 16:11:09 2016 -0800 >> +++ >> b/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java Thu >> Feb 04 11:44:47 2016 -0800 >> @@ -33,6 +33,7 @@ >> import java.util.List; >> import java.util.Map; >> import java.util.Set; >> +import java.util.StringJoiner; >> import java.util.HashSet; >> >> import com.sun.tools.sjavac.Transformer; >> @@ -225,10 +226,7 @@ >> } >> >> String getResult() { >> - String result = ""; >> - for (String s : args) >> - result += s + " "; >> - return result.trim(); >> + return String.join(" ", args); >> } >> >> public void addAll(Collection toAdd) { >> @@ -337,10 +335,11 @@ >> // Helper method to join a list of source locations separated by >> // File.pathSeparator >> private static String concatenateSourceLocations(List >> locs) { >> - String s = ""; >> - for (SourceLocation loc : locs) >> - s += (s.isEmpty() ? "" : java.io.File.pathSeparator) + >> loc.getPath(); >> - return s; >> + StringJoiner joiner = new StringJoiner(java.io.File.pathSeparator); >> + for (SourceLocation loc : locs) { >> + joiner.add(loc.getPath().toString()); >> + } >> + return joiner.toString(); >> } >> >> // OptionHelper that records the traversed options in this Options >> instance. From andreas.lundblad at oracle.com Tue Feb 9 14:57:38 2016 From: andreas.lundblad at oracle.com (Andreas Lundblad) Date: Tue, 9 Feb 2016 15:57:38 +0100 Subject: RFR: Use StringJoiner in sjavac options handling In-Reply-To: <56B91671.8020906@oracle.com> References: <20160208214350.GA14695@e6430> <56B91671.8020906@oracle.com> Message-ID: <20160209145738.GA12434@e6430> On Mon, Feb 08, 2016 at 02:28:01PM -0800, Jonathan Gibbons wrote: > I was hoping you would, but if you'd prefer me to do it, I can. No problem. I'll do it. -- Andreas From gunnar at hibernate.org Tue Feb 9 18:08:55 2016 From: gunnar at hibernate.org (Gunnar Morling) Date: Tue, 9 Feb 2016 19:08:55 +0100 Subject: [Jigsaw] Getting "Bad service configuration file" error with annotation processor In-Reply-To: <56B8ECC1.2080507@oracle.com> References: <56B8CB66.5030008@oracle.com> <56B8ECC1.2080507@oracle.com> Message-ID: Hi, Many thanks for all the replies! > or is it a "pre-Jigsaw"/"JDK8-style" processor with a service configuration file Yes, it's a "pre-Jigsaw" processor; More specifically it's the JBoss Logging processor (see [1], [2] for sources/binary), a tool which creates I18N-capable logger classes from annotated interfaces. I am building a module which contains such annotated interface. Passing the processor and its dependencies through "-processorpath" (instead of "-processormodulepath") did the trick in the end, so thanks for that suggestion. Note that one stumbling block was a NoClassDefFoundError related to javax.annotation.Generated raised from within the processor: The processor adds this annotation to the sources it generates and for that purpose it accesses Generated.class. I added "requires java.annotations.common" to the module-info.java of the module under compilation (i.e. the module to which the processor is applied), but this didn't help. Eventually I could make it work by adding a JAR containing the JSR 250 classes to "-processorpath". But I am wondering whether that's the right approach as these classes are provided by the JDK. Is there a way to have modules such as "java.annotations.common" exposed to "pre-Jigsaw" processors? Thanks, --Gunnar [1] https://github.com/jboss-logging/jboss-logging-tools/blob/2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/apt/LoggingToolsProcessor.java [2] http://search.maven.org/#artifactdetails|org.jboss.logging|jboss-logging-processor|2.0.1.Final|jar From Alan.Bateman at oracle.com Tue Feb 9 20:33:33 2016 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 9 Feb 2016 21:33:33 +0100 Subject: [Jigsaw] Getting "Bad service configuration file" error with annotation processor In-Reply-To: References: <56B8CB66.5030008@oracle.com> <56B8ECC1.2080507@oracle.com> Message-ID: <56BA4D1D.70500@oracle.com> On 09/02/2016 19:08, Gunnar Morling wrote: > : > > Note that one stumbling block was a NoClassDefFoundError related to > javax.annotation.Generated raised from within the processor: The > processor adds this annotation to the sources it generates and for > that purpose it accesses Generated.class. I added "requires > java.annotations.common" to the module-info.java of the module under > compilation (i.e. the module to which the processor is applied), but > this didn't help. > > Eventually I could make it work by adding a JAR containing the JSR 250 > classes to "-processorpath". But I am wondering whether that's the > right approach as these classes are provided by the JDK. Is there a > way to have modules such as "java.annotations.common" exposed to > "pre-Jigsaw" processors? > I assume the issue here is that module java.annotations.common is not in the boot Layer. That is, when you run javac then the initial module is jdk.compiler and the only modules in the boot layer will be jdk.compiler, its transitive dependences, and a few other service provider modules that get located by means of service binding. At run-time then it's possible that javac will load and run annotation processors that have dependences beyond the set of modules that the container (javac in this case) transitively requires. This will explain why you get NoClassDefFoundError when you run a legacy processor. On the other hand, if the processor is a module then I would expect that resolving its initial module will fail. I'm guessing you must have got a ResolutionException, I wouldn't expect javac to hide that. For now then then add -J-addmods -JALL-SYSTEM to the javac command and I expect this will workaround the hissue. Given that javac is a container then we may need to have its launcher add these options. This doesn't help when javac is invoked programmatically of course as whatever is invoking the javax.tools API may have restricted the modules in the boot layer. -Alan. From wieland at testingtech.com Wed Feb 10 10:38:28 2016 From: wieland at testingtech.com (Wieland, Jacob) Date: Wed, 10 Feb 2016 10:38:28 +0000 Subject: Classes of the future Message-ID: Hello folks, is there any plan to get rid of the ridiculously low restrictions on the current class-file-format that seem to be a remnant of another (low-memory) age? The barriers that I continually run into (when generating Java source code) are: - only 64KB bytecode per method (with no really good way of estimation how much source code produces how much bytecode), => especially annoying as the anonymous constructor is also a method and all initializations of final fields need to be part of either the anonymous or a non-anonymous constructor (which cannot be split into several methods, unfortunately). This leads to having to declare the fields as non-final so that the initializing code can be split into normal methods. - only 64K class members (leading to unnatural refraction of classes into sub-classes) - only 64K constants (which is especially annoying when using lots of inner classes as ever inner class consumes at least one constant (I think it is actually 2), so the number of inner classes is implicitly restricted by that (leading to lots of anonymous runnables to wrap the code using the constants) Of course, for every such barrier, I have found workaround solutions, but these both make the code much less readable and often a lot less efficient, and of course, much longer which again is a drain on resources both on memory, storing and compiler-capacity. The other way to go would be to redesign the source-code-to-byte-code mapping so that the generated byte-code always respects the barriers (i.e. implementing the workarounds I now have to do in the source code automatically in the byte-code), but that is probably a much heftier feat than "simply" raising these rather low barriers to a more comfortable height (i.e. 4 bytes instead of 2 should suffice for most cases). BR, Jacob -------------- next part -------------- An HTML attachment was scrubbed... URL: From steff.nicolas at gmail.com Wed Feb 10 17:09:48 2016 From: steff.nicolas at gmail.com (=?UTF-8?Q?St=C3=A9phane_NICOLAS?=) Date: Wed, 10 Feb 2016 09:09:48 -0800 Subject: Invoking code generated by an annotation processor Message-ID: I am facing a problem with Javac : I got a sweet annotation processor that generates a DSL and I invoke the generated code from my main code. Everything works fine except when there is an error in my main code : if I got a compile error in the main code, not related to the generated code, like a missing comma (parsing problem), or calling an inexisting method (linkage problem), then all calls to the annotation processor are marked as errors by the compiler. Ideally I am just looking for a way to get rid of those error messages, and keep only the original one that fails to compile. AFAIK, javac should support this scenario but it doesn't support it in a very convenient way and I don't understand exactly why.. After reafing the javac code, open jdk 7 & 8, I realized that : Annotation processors are not called if there is any error to compile the code. As the annotation processor are not triggered, the calls to generated code get mark as an error. However, I could, by playing with shouldStopPolicy (+if error and if no error) trigger the annotation processor and generate the code. But still, I would receive in this case the errors related to calling the generated code. Like if the generated code was not taken into account, like if I was receiving errors from a previous compilation steps. I understand that javac parses the code, if it fails there, I will receive only an error about the actual problem. And this is great. I just want this error to show up, not any other, and it works fine. (Though I am wondering if this is always true even I clean my build & generated files before compiling) If there is a linkage problem in my original code, like calling an non-existent method, javac will relax the error and trigger the annotation processors and try to let them generate the code to see if the generated code that satisfies the linkage problem. But then, though there is a state in which javac will successfully satisfy all linkage related to generated code but not the other linkage error, I get all calls to generated code marked as errors. This is my problem. It looks like this internal state of the compiler is never accessible and errors returned do not match this state but more probably a previous internal state in which all linkage errors are aggregated and returned. I think there is a solution to achieve what I want but I couldn't find one. And the situation is bad : it may actually cancel the development of the annotation processor lib I am developing. Just because the errors are flooding the actual problem in the code. Would you have some time to advise me, and help me to make the lib work as expected. My goal is just to get only errors that are not related to calling generated code if they are not those who fail the compilation. I don't want to see my errors polluted by those calls if they are not responsible for breaking the compilation. Stephane -------------- next part -------------- An HTML attachment was scrubbed... URL: From jonathan.gibbons at oracle.com Wed Feb 10 19:41:04 2016 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Wed, 10 Feb 2016 11:41:04 -0800 Subject: Invoking code generated by an annotation processor In-Reply-To: References: Message-ID: <56BB9250.20607@oracle.com> On 02/10/2016 09:09 AM, St?phane NICOLAS wrote: > I am facing a problem with Javac : I got a sweet annotation processor > that generates a DSL and I invoke the generated code from my main code. > > Everything works fine except when there is an error in my main code : > if I got a compile error in the main code, not related to the > generated code, like a missing comma (parsing problem), or calling an > inexisting method (linkage problem), then all calls to the annotation > processor are marked as errors by the compiler. > > Ideally I am just looking for a way to get rid of those error > messages, and keep only the original one that fails to compile. > > AFAIK, javac should support this scenario but it doesn't support it in > a very convenient way and I don't understand exactly why.. > > After reafing the javac code, open jdk 7 & 8, I realized that : > > Annotation processors are not called if there is any error to compile > the code. As the annotation processor are not triggered, the calls to > generated code get mark as an error. > > However, I could, by playing with shouldStopPolicy (+if error and if > no error) trigger the annotation processor and generate the code. But > still, I would receive in this case the errors related to calling the > generated code. Like if the generated code was not taken into account, > like if I was receiving errors from a previous compilation steps. > > I understand that javac parses the code, if it fails there, I will > receive only an error about the actual problem. And this is great. I > just want this error to show up, not any other, and it works fine. > (Though I am wondering if this is always true even I clean my build & > generated files before compiling) > > If there is a linkage problem in my original code, like calling an > non-existent method, javac will relax the error and trigger the > annotation processors and try to let them generate the code to see if > the generated code that satisfies the linkage problem. But then, > though there is a state in which javac will successfully satisfy all > linkage related to generated code but not the other linkage error, I > get all calls to generated code marked as errors. This is my problem. > It looks like this internal state of the compiler is never accessible > and errors returned do not match this state but more probably a > previous internal state in which all linkage errors are aggregated and > returned. > > I think there is a solution to achieve what I want but I couldn't find > one. And the situation is bad : it may actually cancel the development > of the annotation processor lib I am developing. Just because the > errors are flooding the actual problem in the code. > > Would you have some time to advise me, and help me to make the lib > work as expected. > My goal is just to get only errors that are not related to calling > generated code if they are not those who fail the compilation. I don't > want to see my errors polluted by those calls if they are not > responsible for breaking the compilation. > > Stephane Stephane, In general, there is no convenient solution for you here, because there is no way for javac to predict what unresolved symbols may or may not be generated by the annotation processor that has yet to be run. And in general, it is not desirable to run annotation processors if the input source code has significant errors, such as syntax errors. -- Jon -------------- next part -------------- An HTML attachment was scrubbed... URL: From steff.nicolas at gmail.com Wed Feb 10 20:59:44 2016 From: steff.nicolas at gmail.com (=?UTF-8?Q?St=C3=A9phane_NICOLAS?=) Date: Wed, 10 Feb 2016 12:59:44 -0800 Subject: Invoking code generated by an annotation processor In-Reply-To: <56BB9250.20607@oracle.com> References: <56BB9250.20607@oracle.com> Message-ID: Thanks Jon for your fast answer. It's quite disappointing but it's better to know it early. It's sad to see how much effort we have put in our annotation processor, that it's a good idea but fails because of some general java ecosystem issue. Though, talking of the issue with team mates, it became more clear. Let me try to rephrase them more accurately than in my first mail. It seems to me that the design of javac could be improved to accommodate these 2 scenarios : 1. in case of a parse error (for instance a missing ; a bad brace, etc.) , javac should stop everything and report the actual problem, without getting any further into the analysis and not report any linkage problem (because javac would know that annotation processors ain't gonna run and that can create false positive about missing linkages. All other parse errors should be reported.). It seems to me this would be a healthy "fail early" design. 2. in case of a linkage error (for instance having a non existing import / calling a non existing method, etc.) then we should run the annotation processors on the partial AST. This mechanism is already in place to accomodate code generation. Then the linkage problems should be resolved and take into account the generated code, and only the remaining problems should show up. This is where javac actually fails because it reports all problems, including those that can be resolved by the code that is actually generated. Javac reports problem from a previous internal stage, it doesn't match the latest state it could reach internally where only 1 problem could not be resolved, the one that was not related to invoking generated code, it reports all linkages problem exactly like if no code was generated and no annotation processor had run. Really, there is no way for javac to support those 2 scenarios ? I got the strong feeling that it should but I understand my knowledge of javac has huge holes. I have been surprised by the complexity of the compiler's code. Thx again for your answer, it's been tremendously appreciated; there are just a handful people would could have been able to answer my question I am very happy someone actually did take the time to do it. Stephane 2016-02-10 11:41 GMT-08:00 Jonathan Gibbons : > > > On 02/10/2016 09:09 AM, St?phane NICOLAS wrote: > > I am facing a problem with Javac : I got a sweet annotation processor that > generates a DSL and I invoke the generated code from my main code. > > Everything works fine except when there is an error in my main code : if I > got a compile error in the main code, not related to the generated code, > like a missing comma (parsing problem), or calling an inexisting method > (linkage problem), then all calls to the annotation processor are marked as > errors by the compiler. > > Ideally I am just looking for a way to get rid of those error messages, > and keep only the original one that fails to compile. > > AFAIK, javac should support this scenario but it doesn't support it in a > very convenient way and I don't understand exactly why.. > > After reafing the javac code, open jdk 7 & 8, I realized that : > > Annotation processors are not called if there is any error to compile the > code. As the annotation processor are not triggered, the calls to generated > code get mark as an error. > > However, I could, by playing with shouldStopPolicy (+if error and if no > error) trigger the annotation processor and generate the code. But still, I > would receive in this case the errors related to calling the generated > code. Like if the generated code was not taken into account, like if I was > receiving errors from a previous compilation steps. > > I understand that javac parses the code, if it fails there, I will receive > only an error about the actual problem. And this is great. I just want this > error to show up, not any other, and it works fine. (Though I am wondering > if this is always true even I clean my build & generated files before > compiling) > > If there is a linkage problem in my original code, like calling an > non-existent method, javac will relax the error and trigger the annotation > processors and try to let them generate the code to see if the generated > code that satisfies the linkage problem. But then, though there is a state > in which javac will successfully satisfy all linkage related to generated > code but not the other linkage error, I get all calls to generated code > marked as errors. This is my problem. It looks like this internal state of > the compiler is never accessible and errors returned do not match this > state but more probably a previous internal state in which all linkage > errors are aggregated and returned. > > I think there is a solution to achieve what I want but I couldn't find > one. And the situation is bad : it may actually cancel the development of > the annotation processor lib I am developing. Just because the errors are > flooding the actual problem in the code. > > Would you have some time to advise me, and help me to make the lib work as > expected. > My goal is just to get only errors that are not related to calling > generated code if they are not those who fail the compilation. I don't want > to see my errors polluted by those calls if they are not responsible for > breaking the compilation. > > Stephane > > > Stephane, > > In general, there is no convenient solution for you here, because there is > no way for javac to predict what unresolved symbols may or may not be > generated by the annotation processor that has yet to be run. And in > general, it is not desirable to run annotation processors if the input > source code has significant errors, such as syntax errors. > > -- Jon > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jonathan.gibbons at oracle.com Wed Feb 10 21:25:41 2016 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Wed, 10 Feb 2016 13:25:41 -0800 Subject: Invoking code generated by an annotation processor In-Reply-To: References: <56BB9250.20607@oracle.com> Message-ID: <56BBAAD5.7080807@oracle.com> On 02/10/2016 12:59 PM, St?phane NICOLAS wrote: > Thanks Jon for your fast answer. It's quite disappointing but it's > better to know it early. > It's sad to see how much effort we have put in our annotation > processor, that it's a good idea but fails because of some general > java ecosystem issue. > > Though, talking of the issue with team mates, it became more clear. > Let me try to rephrase them more accurately than in my first mail. > > It seems to me that the design of javac could be improved to > accommodate these 2 scenarios : > > 1. in case of a parse error (for instance a missing ; a bad brace, > etc.) , javac should stop everything and report the actual > problem, without getting any further into the analysis and not > report any linkage problem (because javac would know that > annotation processors ain't gonna run and that can create false > positive about missing linkages. All other parse errors should be > reported.). It seems to me this would be a healthy "fail early" > design. > This is the intent. Generally, javac is supposed to fail reasonably fast in general, and in that case in particular. If you are seeing otherwise, please provide a test case, including the version of javac you are using. > 1. in case of a linkage error (for instance having a non existing > import / calling a non existing method, etc.) then we should run > the annotation processors on the partial AST. This mechanism is > already in place to accomodate code generation. > Then the linkage problems should be resolved and take into account > the generated code, and only the remaining problems should show > up. This is where javac actually fails because it reports all > problems, including those that can be resolved by the code that is > actually generated. Javac reports problem from a previous internal > stage, it doesn't match the latest state it could reach internally > where only 1 problem could not be resolved, the one that was not > related to invoking generated code, it reports all linkages > problem exactly like if no code was generated and no annotation > processor had run. > That is the intent. > Really, there is no way for javac to support those 2 scenarios ? I got > the strong feeling that it should but I understand my knowledge of > javac has huge holes. I have been surprised by the complexity of the > compiler's code. > > Thx again for your answer, it's been tremendously appreciated; there > are just a handful people would could have been able to answer my > question I am very happy someone actually did take the time to do it. > > Stephane > > 2016-02-10 11:41 GMT-08:00 Jonathan Gibbons > >: > > > > On 02/10/2016 09:09 AM, St?phane NICOLAS wrote: >> I am facing a problem with Javac : I got a sweet annotation >> processor that generates a DSL and I invoke the generated code >> from my main code. >> >> Everything works fine except when there is an error in my main >> code : if I got a compile error in the main code, not related to >> the generated code, like a missing comma (parsing problem), or >> calling an inexisting method (linkage problem), then all calls to >> the annotation processor are marked as errors by the compiler. >> >> Ideally I am just looking for a way to get rid of those error >> messages, and keep only the original one that fails to compile. >> >> AFAIK, javac should support this scenario but it doesn't support >> it in a very convenient way and I don't understand exactly why.. >> >> After reafing the javac code, open jdk 7 & 8, I realized that : >> >> Annotation processors are not called if there is any error to >> compile the code. As the annotation processor are not triggered, >> the calls to generated code get mark as an error. >> >> However, I could, by playing with shouldStopPolicy (+if error and >> if no error) trigger the annotation processor and generate the >> code. But still, I would receive in this case the errors related >> to calling the generated code. Like if the generated code was not >> taken into account, like if I was receiving errors from a >> previous compilation steps. >> >> I understand that javac parses the code, if it fails there, I >> will receive only an error about the actual problem. And this is >> great. I just want this error to show up, not any other, and it >> works fine. (Though I am wondering if this is always true even I >> clean my build & generated files before compiling) >> >> If there is a linkage problem in my original code, like calling >> an non-existent method, javac will relax the error and trigger >> the annotation processors and try to let them generate the code >> to see if the generated code that satisfies the linkage problem. >> But then, though there is a state in which javac will >> successfully satisfy all linkage related to generated code but >> not the other linkage error, I get all calls to generated code >> marked as errors. This is my problem. It looks like this internal >> state of the compiler is never accessible and errors returned do >> not match this state but more probably a previous internal state >> in which all linkage errors are aggregated and returned. >> >> I think there is a solution to achieve what I want but I couldn't >> find one. And the situation is bad : it may actually cancel the >> development of the annotation processor lib I am developing. Just >> because the errors are flooding the actual problem in the code. >> >> Would you have some time to advise me, and help me to make the >> lib work as expected. >> My goal is just to get only errors that are not related to >> calling generated code if they are not those who fail the >> compilation. I don't want to see my errors polluted by those >> calls if they are not responsible for breaking the compilation. >> >> Stephane > > Stephane, > > In general, there is no convenient solution for you here, because > there is no way for javac to predict what unresolved symbols may > or may not be generated by the annotation processor that has yet > to be run. And in general, it is not desirable to run annotation > processors if the input source code has significant errors, such > as syntax errors. > > -- Jon > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From steff.nicolas at gmail.com Thu Feb 11 18:44:49 2016 From: steff.nicolas at gmail.com (=?UTF-8?Q?St=C3=A9phane_NICOLAS?=) Date: Thu, 11 Feb 2016 10:44:49 -0800 Subject: Invoking code generated by an annotation processor In-Reply-To: <56BBAAD5.7080807@oracle.com> References: <56BB9250.20607@oracle.com> <56BBAAD5.7080807@oracle.com> Message-ID: Hey Jon, we are going to create an example based on our annotation processor. It will come in the form of a github repo, 1 branch that compiles fine, 2 branches to illustrate different compile problems. Everything is mavenized so it should work out of the box for you. We will also tell you what error messages we have on the 2 failing branches, actual and expected behavior, and provide you with our javac version(s). We hope this can help, thank you very much for your answers. St?phane 2016-02-10 13:25 GMT-08:00 Jonathan Gibbons : > > > On 02/10/2016 12:59 PM, St?phane NICOLAS wrote: > > Thanks Jon for your fast answer. It's quite disappointing but it's better > to know it early. > It's sad to see how much effort we have put in our annotation processor, > that it's a good idea but fails because of some general java ecosystem > issue. > > Though, talking of the issue with team mates, it became more clear. Let me > try to rephrase them more accurately than in my first mail. > > It seems to me that the design of javac could be improved to accommodate > these 2 scenarios : > > 1. in case of a parse error (for instance a missing ; a bad brace, > etc.) , javac should stop everything and report the actual problem, without > getting any further into the analysis and not report any linkage problem > (because javac would know that annotation processors ain't gonna run and > that can create false positive about missing linkages. All other parse > errors should be reported.). It seems to me this would be a healthy "fail > early" design. > > > This is the intent. Generally, javac is supposed to fail reasonably fast > in general, and in that case in particular. If you are seeing > otherwise, please provide a test case, including the version of javac you > are using. > > > > > 1. in case of a linkage error (for instance having a non existing > import / calling a non existing method, etc.) then we should run the > annotation processors on the partial AST. This mechanism is already in > place to accomodate code generation. > Then the linkage problems should be resolved and take into account the > generated code, and only the remaining problems should show up. This is > where javac actually fails because it reports all problems, including those > that can be resolved by the code that is actually generated. Javac reports > problem from a previous internal stage, it doesn't match the latest state > it could reach internally where only 1 problem could not be resolved, the > one that was not related to invoking generated code, it reports all > linkages problem exactly like if no code was generated and no annotation > processor had run. > > > That is the intent. > > Really, there is no way for javac to support those 2 scenarios ? I got the > strong feeling that it should but I understand my knowledge of javac has > huge holes. I have been surprised by the complexity of the compiler's code. > > Thx again for your answer, it's been tremendously appreciated; there are > just a handful people would could have been able to answer my question I am > very happy someone actually did take the time to do it. > > Stephane > > 2016-02-10 11:41 GMT-08:00 Jonathan Gibbons : > >> >> >> On 02/10/2016 09:09 AM, St?phane NICOLAS wrote: >> >> I am facing a problem with Javac : I got a sweet annotation processor >> that generates a DSL and I invoke the generated code from my main code. >> >> Everything works fine except when there is an error in my main code : if >> I got a compile error in the main code, not related to the generated code, >> like a missing comma (parsing problem), or calling an inexisting method >> (linkage problem), then all calls to the annotation processor are marked as >> errors by the compiler. >> >> Ideally I am just looking for a way to get rid of those error messages, >> and keep only the original one that fails to compile. >> >> AFAIK, javac should support this scenario but it doesn't support it in a >> very convenient way and I don't understand exactly why.. >> >> After reafing the javac code, open jdk 7 & 8, I realized that : >> >> Annotation processors are not called if there is any error to compile the >> code. As the annotation processor are not triggered, the calls to generated >> code get mark as an error. >> >> However, I could, by playing with shouldStopPolicy (+if error and if no >> error) trigger the annotation processor and generate the code. But still, I >> would receive in this case the errors related to calling the generated >> code. Like if the generated code was not taken into account, like if I was >> receiving errors from a previous compilation steps. >> >> I understand that javac parses the code, if it fails there, I will >> receive only an error about the actual problem. And this is great. I just >> want this error to show up, not any other, and it works fine. (Though I am >> wondering if this is always true even I clean my build & generated files >> before compiling) >> >> If there is a linkage problem in my original code, like calling an >> non-existent method, javac will relax the error and trigger the annotation >> processors and try to let them generate the code to see if the generated >> code that satisfies the linkage problem. But then, though there is a state >> in which javac will successfully satisfy all linkage related to generated >> code but not the other linkage error, I get all calls to generated code >> marked as errors. This is my problem. It looks like this internal state of >> the compiler is never accessible and errors returned do not match this >> state but more probably a previous internal state in which all linkage >> errors are aggregated and returned. >> >> I think there is a solution to achieve what I want but I couldn't find >> one. And the situation is bad : it may actually cancel the development of >> the annotation processor lib I am developing. Just because the errors are >> flooding the actual problem in the code. >> >> Would you have some time to advise me, and help me to make the lib work >> as expected. >> My goal is just to get only errors that are not related to calling >> generated code if they are not those who fail the compilation. I don't want >> to see my errors polluted by those calls if they are not responsible for >> breaking the compilation. >> >> Stephane >> >> >> Stephane, >> >> In general, there is no convenient solution for you here, because there >> is no way for javac to predict what unresolved symbols may or may not be >> generated by the annotation processor that has yet to be run. And in >> general, it is not desirable to run annotation processors if the input >> source code has significant errors, such as syntax errors. >> >> -- Jon >> > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jonathan.gibbons at oracle.com Thu Feb 11 19:03:23 2016 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Thu, 11 Feb 2016 11:03:23 -0800 Subject: Invoking code generated by an annotation processor In-Reply-To: References: <56BB9250.20607@oracle.com> <56BBAAD5.7080807@oracle.com> Message-ID: <56BCDAFB.3040107@oracle.com> St?phane, Can you reduce the test case down to a simple one(s) that you can post here? -- Jon On 02/11/2016 10:44 AM, St?phane NICOLAS wrote: > Hey Jon, > > we are going to create an example based on our annotation processor. > It will come in the form of a github repo, 1 branch that compiles > fine, 2 branches to illustrate different compile problems. Everything > is mavenized so it should work out of the box for you. We will also > tell you what error messages we have on the 2 failing branches, actual > and expected behavior, and provide you with our javac version(s). > > We hope this can help, thank you very much for your answers. > > St?phane > > > 2016-02-10 13:25 GMT-08:00 Jonathan Gibbons > >: > > > > On 02/10/2016 12:59 PM, St?phane NICOLAS wrote: >> Thanks Jon for your fast answer. It's quite disappointing but >> it's better to know it early. >> It's sad to see how much effort we have put in our annotation >> processor, that it's a good idea but fails because of some >> general java ecosystem issue. >> >> Though, talking of the issue with team mates, it became more >> clear. Let me try to rephrase them more accurately than in my >> first mail. >> >> It seems to me that the design of javac could be improved to >> accommodate these 2 scenarios : >> >> 1. in case of a parse error (for instance a missing ; a bad >> brace, etc.) , javac should stop everything and report the >> actual problem, without getting any further into the analysis >> and not report any linkage problem (because javac would know >> that annotation processors ain't gonna run and that can >> create false positive about missing linkages. All other parse >> errors should be reported.). It seems to me this would be a >> healthy "fail early" design. >> > > This is the intent. Generally, javac is supposed to fail > reasonably fast in general, and in that case in particular. If > you are seeing otherwise, please provide a test case, including > the version of javac you are using. > > > >> 1. in case of a linkage error (for instance having a non >> existing import / calling a non existing method, etc.) then >> we should run the annotation processors on the partial AST. >> This mechanism is already in place to accomodate code >> generation. >> Then the linkage problems should be resolved and take into >> account the generated code, and only the remaining problems >> should show up. This is where javac actually fails because it >> reports all problems, including those that can be resolved by >> the code that is actually generated. Javac reports problem >> from a previous internal stage, it doesn't match the latest >> state it could reach internally where only 1 problem could >> not be resolved, the one that was not related to invoking >> generated code, it reports all linkages problem exactly like >> if no code was generated and no annotation processor had run. >> > > That is the intent. > >> Really, there is no way for javac to support those 2 scenarios ? >> I got the strong feeling that it should but I understand my >> knowledge of javac has huge holes. I have been surprised by the >> complexity of the compiler's code. >> >> Thx again for your answer, it's been tremendously appreciated; >> there are just a handful people would could have been able to >> answer my question I am very happy someone actually did take the >> time to do it. >> >> Stephane >> >> 2016-02-10 11:41 GMT-08:00 Jonathan Gibbons >> >: >> >> >> >> On 02/10/2016 09:09 AM, St?phane NICOLAS wrote: >>> I am facing a problem with Javac : I got a sweet annotation >>> processor that generates a DSL and I invoke the generated >>> code from my main code. >>> >>> Everything works fine except when there is an error in my >>> main code : if I got a compile error in the main code, not >>> related to the generated code, like a missing comma (parsing >>> problem), or calling an inexisting method (linkage problem), >>> then all calls to the annotation processor are marked as >>> errors by the compiler. >>> >>> Ideally I am just looking for a way to get rid of those >>> error messages, and keep only the original one that fails to >>> compile. >>> >>> AFAIK, javac should support this scenario but it doesn't >>> support it in a very convenient way and I don't understand >>> exactly why.. >>> >>> After reafing the javac code, open jdk 7 & 8, I realized that : >>> >>> Annotation processors are not called if there is any error >>> to compile the code. As the annotation processor are not >>> triggered, the calls to generated code get mark as an error. >>> >>> However, I could, by playing with shouldStopPolicy (+if >>> error and if no error) trigger the annotation processor and >>> generate the code. But still, I would receive in this case >>> the errors related to calling the generated code. Like if >>> the generated code was not taken into account, like if I was >>> receiving errors from a previous compilation steps. >>> >>> I understand that javac parses the code, if it fails there, >>> I will receive only an error about the actual problem. And >>> this is great. I just want this error to show up, not any >>> other, and it works fine. (Though I am wondering if this is >>> always true even I clean my build & generated files before >>> compiling) >>> >>> If there is a linkage problem in my original code, like >>> calling an non-existent method, javac will relax the error >>> and trigger the annotation processors and try to let them >>> generate the code to see if the generated code that >>> satisfies the linkage problem. But then, though there is a >>> state in which javac will successfully satisfy all linkage >>> related to generated code but not the other linkage error, I >>> get all calls to generated code marked as errors. This is my >>> problem. It looks like this internal state of the compiler >>> is never accessible and errors returned do not match this >>> state but more probably a previous internal state in which >>> all linkage errors are aggregated and returned. >>> >>> I think there is a solution to achieve what I want but I >>> couldn't find one. And the situation is bad : it may >>> actually cancel the development of the annotation processor >>> lib I am developing. Just because the errors are flooding >>> the actual problem in the code. >>> >>> Would you have some time to advise me, and help me to make >>> the lib work as expected. >>> My goal is just to get only errors that are not related to >>> calling generated code if they are not those who fail the >>> compilation. I don't want to see my errors polluted by those >>> calls if they are not responsible for breaking the compilation. >>> >>> Stephane >> >> Stephane, >> >> In general, there is no convenient solution for you here, >> because there is no way for javac to predict what unresolved >> symbols may or may not be generated by the annotation >> processor that has yet to be run. And in general, it is not >> desirable to run annotation processors if the input source >> code has significant errors, such as syntax errors. >> >> -- Jon >> >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From joe.darcy at oracle.com Sun Feb 14 02:18:01 2016 From: joe.darcy at oracle.com (joe darcy) Date: Sat, 13 Feb 2016 18:18:01 -0800 Subject: JDK 9 RFR of JDK-6469561,javadoc for annotation types should not display "public abstract" modifiers on methods Message-ID: <56BFE3D9.8000402@oracle.com> Hello, Please review the fix for JDK-6469561,javadoc for annotation types should not display "public abstract" modifiers on methods http://cr.openjdk.java.net/~darcy/6469561.0/ In brief, just as methods on interface types are implicitly public and abstract, so are methods on annotation types (technically annotation types are a special kind of interface type). While javadoc elides "public abstract" for methods on interfaces, it does not do so for methods on annotation type. The patch makes the behavior of javadoc consistent in this case. With the patch, all langtools regression tests pass and the modified test fails (as expected) if run against JDK 9 b104. Thanks, -Joe From joe.darcy at oracle.com Sun Feb 14 05:50:55 2016 From: joe.darcy at oracle.com (joe darcy) Date: Sat, 13 Feb 2016 21:50:55 -0800 Subject: JDK 9 RFR of JDK-6469562: Use compact notation to display annotation values Message-ID: <56C015BF.6090406@oracle.com> Hello, Please review these changes to address JDK-6469562: Use compact notation to display annotation values http://cr.openjdk.java.net/~darcy/6469562.0/ In brief, when it is not required the noisy "value=" portion of annotation is now omitted in javadoc leading to a more concise display. (The to the files used to generated the javadoc are not strictly necessary, but they do demonstrate that the "value=" is superfluous at a source level.) Thanks, -Joe From jonathan.gibbons at oracle.com Sun Feb 14 16:31:00 2016 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Sun, 14 Feb 2016 08:31:00 -0800 Subject: JDK 9 RFR of JDK-6469561,javadoc for annotation types should not display "public abstract" modifiers on methods In-Reply-To: <56BFE3D9.8000402@oracle.com> References: <56BFE3D9.8000402@oracle.com> Message-ID: <56C0ABC4.4070100@oracle.com> Joe, The code looks OK, but I have to wonder why the code needs any tests on the type of the Writer, and why it cannot do all the necessary analysis on member and its enclosing element. -- Jon On 02/13/2016 06:18 PM, joe darcy wrote: > Hello, > > Please review the fix for > > JDK-6469561,javadoc for annotation types should not display > "public abstract" modifiers on methods > http://cr.openjdk.java.net/~darcy/6469561.0/ > > In brief, just as methods on interface types are implicitly public and > abstract, so are methods on annotation types (technically annotation > types are a special kind of interface type). While javadoc elides > "public abstract" for methods on interfaces, it does not do so for > methods on annotation type. > > The patch makes the behavior of javadoc consistent in this case. > > With the patch, all langtools regression tests pass and the modified > test fails (as expected) if run against JDK 9 b104. > > Thanks, > > -Joe From sven.reimers at gmail.com Mon Feb 15 14:34:22 2016 From: sven.reimers at gmail.com (Sven Reimers) Date: Mon, 15 Feb 2016 15:34:22 +0100 Subject: Compiler creates broken classfiles although errors are shown in output Message-ID: Hi, I just ran into https://bugs.openjdk.java.net/browse/JDK-8145208 The main problem is not to fix the error, but our continuous integration is not creating breaking builds, so the error can get unnoticed into builds and fails at runtime. Any idea if this can be fixed in an upcoming jdk 8u release? Any idea how to make the build break in this case? Thanks for your help -Sven -------------- next part -------------- An HTML attachment was scrubbed... URL: From jan.lahoda at oracle.com Mon Feb 15 15:30:04 2016 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Mon, 15 Feb 2016 16:30:04 +0100 Subject: Compiler creates broken classfiles although errors are shown in output In-Reply-To: References: Message-ID: <56C1EEFC.8010406@oracle.com> Hi Sven, Would you have a testcase on which this can be seen? Thanks, Jan On 15.2.2016 15:34, Sven Reimers wrote: > Hi, > > I just ran into https://bugs.openjdk.java.net/browse/JDK-8145208 > > The main problem is not to fix the error, but our continuous > integration is not creating breaking builds, so the error can get > unnoticed into builds and fails at runtime. > > Any idea if this can be fixed in an upcoming jdk 8u release? > > Any idea how to make the build break in this case? > > Thanks for your help > > -Sven > From sven.reimers at gmail.com Mon Feb 15 16:02:00 2016 From: sven.reimers at gmail.com (Sven Reimers) Date: Mon, 15 Feb 2016 17:02:00 +0100 Subject: Compiler creates broken classfiles although errors are shown in output In-Reply-To: <56C1EEFC.8010406@oracle.com> References: <56C1EEFC.8010406@oracle.com> Message-ID: There is an example in here http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-2156366.html Area: Tools / javac Synopsis Interfaces need to be present when compiling against their implementations Description When compiling a class against another class implementing an interface which is defined in yet another class file, such class file (where interface is defined) must be available in the class path used by javac during compilation. This is a new requirement as of JDK 8 - a failure to do so will result in a compilation error. Example: Client.java: import p1.A; class Client { void test() { new A.m(); } } p1/A.java: package p1; public class A implements I { public void m() { } } p1/I.java: package p1; public interface I { void m(); } If neither p1/I.java nor p1/I.class are available when compiling Client.java, the following error will be displayed: Client.java: error: cannot access I new A().m(); ^ class file for p1.I not found If this does not reproduce the problem, I will try to reduce our code sample Thanks Sven Hi Sven, Would you have a testcase on which this can be seen? Thanks, Jan On 15.2.2016 15:34, Sven Reimers wrote: > > Hi, > > I just ran into https://bugs.openjdk.java.net/browse/JDK-8145208 > > The main problem is not to fix the error, but our continuous > integration is not creating breaking builds, so the error can get > unnoticed into builds and fails at runtime. > > Any idea if this can be fixed in an upcoming jdk 8u release? > > Any idea how to make the build break in this case? > > Thanks for your help > > -Sven > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jonathan.gibbons at oracle.com Mon Feb 15 16:21:28 2016 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Mon, 15 Feb 2016 08:21:28 -0800 Subject: Compiler creates broken classfiles although errors are shown in output In-Reply-To: References: <56C1EEFC.8010406@oracle.com> Message-ID: <56C1FB08.2040809@oracle.com> What sort of "broken classfiles" are you seeing? What exit code from javac are you seeing? -- Jon On 02/15/2016 08:02 AM, Sven Reimers wrote: > > There is an example in here > > http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-2156366.html > > Area: Tools / javac > > Synopsis > > Interfaces need to be present when compiling against their implementations > > Description > > When compiling a class against another class implementing an interface > which is defined in yet another class file, such class file (where > interface is defined) must be available in the class path used > by javac during compilation. This is a new requirement as of JDK 8 - a > failure to do so will result in a compilation error. > > Example: > > Client.java: > > import p1.A; > > class Client { > > void test() { > > new A.m(); > > } > > } > > p1/A.java: > > package p1; > > public class A implements I { > > public void m() { } > > } > > p1/I.java: > > package p1; > > public interface I { > > void m(); > > } > > If neither p1/I.java nor p1/I.class are available when compiling > Client.java, the following error will be displayed: > > Client.java: error: cannot access I > > new A().m(); > > ^ > > class file for p1.I not found > > > If this does not reproduce the problem, I will try to reduce our code > sample > > Thanks > > Sven > > > Hi Sven, > > Would you have a testcase on which this can be seen? > > Thanks, > Jan > > On 15.2.2016 15:34, Sven Reimers wrote: > > > > > Hi, > > > > I just ran intohttps://bugs.openjdk.java.net/browse/JDK-8145208 > > > > > The main problem is not to fix the error, but our continuous > > integration is not creating breaking builds, so the error can get > > unnoticed into builds and fails at runtime. > > > > Any idea if this can be fixed in an upcoming jdk 8u release? > > > > Any idea how to make the build break in this case? > > > > Thanks for your help > > > > -Sven > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From sven.reimers at gmail.com Mon Feb 15 16:47:15 2016 From: sven.reimers at gmail.com (Sven Reimers) Date: Mon, 15 Feb 2016 17:47:15 +0100 Subject: Compiler creates broken classfiles although errors are shown in output In-Reply-To: <56C1FB08.2040809@oracle.com> References: <56C1EEFC.8010406@oracle.com> <56C1FB08.2040809@oracle.com> Message-ID: Due to missing interface classfiles wrong contents is generated (not illegal), e. g. An instance of fails n case of missing transitive interface which is ok if interface is available at compilation time. It seems (I believe) the exit code is 0.. If necessary I will try to get more details and slimmed down example code. Thanks -Sven Am 15.02.2016 17:21 schrieb "Jonathan Gibbons" : > What sort of "broken classfiles" are you seeing? > > What exit code from javac are you seeing? > > -- Jon > > > On 02/15/2016 08:02 AM, Sven Reimers wrote: > > There is an example in here > > > http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-2156366.html > > Area: Tools / javac > > Synopsis > > Interfaces need to be present when compiling against their implementations > > Description > > When compiling a class against another class implementing an interface > which is defined in yet another class file, such class file (where > interface is defined) must be available in the class path used > by javac during compilation. This is a new requirement as of JDK 8 - a > failure to do so will result in a compilation error. > > Example: > > Client.java: > > import p1.A; > > class Client { > > void test() { > > new A.m(); > > } > > } > > > > p1/A.java: > > package p1; > > public class A implements I { > > public void m() { } > > } > > p1/I.java: > > package p1; > > public interface I { > > void m(); > > } > > > > If neither p1/I.java nor p1/I.class are available when compiling > Client.java, the following error will be displayed: > > Client.java: error: cannot access I > > new A().m(); > > ^ > > class file for p1.I not found > > > If this does not reproduce the problem, I will try to reduce our code > sample > > Thanks > > Sven > > > Hi Sven, > > Would you have a testcase on which this can be seen? > > Thanks, > Jan > > On 15.2.2016 15:34, Sven Reimers wrote: > > > > > Hi, > > > > I just ran into https://bugs.openjdk.java.net/browse/JDK-8145208 > > > > The main problem is not to fix the error, but our continuous > > integration is not creating breaking builds, so the error can get > > unnoticed into builds and fails at runtime. > > > > Any idea if this can be fixed in an upcoming jdk 8u release? > > > > Any idea how to make the build break in this case? > > > > Thanks for your help > > > > -Sven > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From joe.darcy at oracle.com Mon Feb 15 18:24:02 2016 From: joe.darcy at oracle.com (joe darcy) Date: Mon, 15 Feb 2016 10:24:02 -0800 Subject: JDK 9 RFR of JDK-6469561, javadoc for annotation types should not display "public abstract" modifiers on methods In-Reply-To: <56C0ABC4.4070100@oracle.com> References: <56BFE3D9.8000402@oracle.com> <56C0ABC4.4070100@oracle.com> Message-ID: <56C217C2.3060806@oracle.com> Hi Jon, I was replicating the coding patterns of the surrounding code. I'm not familiar with all the levels of indirection that may be in play here. In the standard setup, annotation types use a different writer than the other three kinds of types, classes, enum, and interfaces. If the intention of the instance of checks to not unduly affect the behavior of other potential kinds of writers? -Joe On 2/14/2016 8:31 AM, Jonathan Gibbons wrote: > Joe, > > The code looks OK, but I have to wonder why the code needs any tests > on the type of the Writer, and why it cannot do all the necessary > analysis on member and its enclosing element. > > -- Jon > > > On 02/13/2016 06:18 PM, joe darcy wrote: >> Hello, >> >> Please review the fix for >> >> JDK-6469561,javadoc for annotation types should not display >> "public abstract" modifiers on methods >> http://cr.openjdk.java.net/~darcy/6469561.0/ >> >> In brief, just as methods on interface types are implicitly public >> and abstract, so are methods on annotation types (technically >> annotation types are a special kind of interface type). While javadoc >> elides "public abstract" for methods on interfaces, it does not do so >> for methods on annotation type. >> >> The patch makes the behavior of javadoc consistent in this case. >> >> With the patch, all langtools regression tests pass and the modified >> test fails (as expected) if run against JDK 9 b104. >> >> Thanks, >> >> -Joe > From jonathan.gibbons at oracle.com Mon Feb 15 18:29:41 2016 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Mon, 15 Feb 2016 10:29:41 -0800 Subject: JDK 9 RFR of JDK-6469561,javadoc for annotation types should not display "public abstract" modifiers on methods In-Reply-To: <56C217C2.3060806@oracle.com> References: <56BFE3D9.8000402@oracle.com> <56C0ABC4.4070100@oracle.com> <56C217C2.3060806@oracle.com> Message-ID: <56C21915.8040802@oracle.com> I agree that you have matched the coding standards of the surrounding code, and for that, the code gets an OK. But, the code should (ideally) be just using the Language Model API to determine whether a type is an annotation type or not, and so if we don't change this now, we should file a follow-up fix-it ticket for the javadoc team. There may be other instances of the anti-pattern in the code that we should check for and fix. -- Jon On 02/15/2016 10:24 AM, joe darcy wrote: > Hi Jon, > > I was replicating the coding patterns of the surrounding code. I'm not > familiar with all the levels of indirection that may be in play here. > In the standard setup, annotation types use a different writer than > the other three kinds of types, classes, enum, and interfaces. > > If the intention of the instance of checks to not unduly affect the > behavior of other potential kinds of writers? > > -Joe > > On 2/14/2016 8:31 AM, Jonathan Gibbons wrote: >> Joe, >> >> The code looks OK, but I have to wonder why the code needs any tests >> on the type of the Writer, and why it cannot do all the necessary >> analysis on member and its enclosing element. >> >> -- Jon >> >> >> On 02/13/2016 06:18 PM, joe darcy wrote: >>> Hello, >>> >>> Please review the fix for >>> >>> JDK-6469561,javadoc for annotation types should not display >>> "public abstract" modifiers on methods >>> http://cr.openjdk.java.net/~darcy/6469561.0/ >>> >>> In brief, just as methods on interface types are implicitly public >>> and abstract, so are methods on annotation types (technically >>> annotation types are a special kind of interface type). While >>> javadoc elides "public abstract" for methods on interfaces, it does >>> not do so for methods on annotation type. >>> >>> The patch makes the behavior of javadoc consistent in this case. >>> >>> With the patch, all langtools regression tests pass and the modified >>> test fails (as expected) if run against JDK 9 b104. >>> >>> Thanks, >>> >>> -Joe >> > From jan.lahoda at oracle.com Mon Feb 15 19:03:01 2016 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Mon, 15 Feb 2016 20:03:01 +0100 Subject: Compiler creates broken classfiles although errors are shown in output In-Reply-To: References: <56C1EEFC.8010406@oracle.com> Message-ID: <56C220E5.4080104@oracle.com> Hi Sven, I tried the example with: $ javac -fullversion javac full version "1.8.0_40-b25" And it produced: $ javac Client.java Client.java:7: error: cannot access I new A().m(); ^ class file for p1.I not found 1 error No classfile was written. With: $ javac -fullversion javac full version "1.7.0_45-b35" $ javac Client.java produced no errors, and written a (correct as far as I can tell) classfile (equivalent to a classfile written when I.class is available). Do you have a testcase where javac produces an error, but writes an (incorrect) classfile? Thanks, Jan On 15.2.2016 17:02, Sven Reimers wrote: > There is an example in here > > http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-2156366.html > > Area: Tools / javac > > Synopsis > > Interfaces need to be present when compiling against their implementations > > Description > > When compiling a class against another class implementing an interface > which is defined in yet another class file, such class file (where > interface is defined) must be available in the class path used > by javac during compilation. This is a new requirement as of JDK 8 - a > failure to do so will result in a compilation error. > > Example: > > Client.java: > > import p1.A; > > class Client { > > void test() { > > new A.m(); > > } > > } > > p1/A.java: > > package p1; > > public class A implements I { > > public void m() { } > > } > > p1/I.java: > > package p1; > > public interface I { > > void m(); > > } > > If neither p1/I.java nor p1/I.class are available when compiling > Client.java, the following error will be displayed: > > Client.java: error: cannot access I > > new A().m(); > > ^ > > class file for p1.I not found > > > If this does not reproduce the problem, I will try to reduce our code sample > > Thanks > > Sven > > > Hi Sven, > > Would you have a testcase on which this can be seen? > > Thanks, > Jan > > On 15.2.2016 15:34, Sven Reimers wrote: > > > > > Hi, > > > > I just ran intohttps://bugs.openjdk.java.net/browse/JDK-8145208 > > > > > The main problem is not to fix the error, but our continuous > > integration is not creating breaking builds, so the error can get > > unnoticed into builds and fails at runtime. > > > > Any idea if this can be fixed in an upcoming jdk 8u release? > > > > Any idea how to make the build break in this case? > > > > Thanks for your help > > > > -Sven > > > From jonathan.gibbons at oracle.com Mon Feb 15 22:55:08 2016 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Mon, 15 Feb 2016 14:55:08 -0800 Subject: RFR: 8149772: cleanup handling of -encoding in JavacFileManager Message-ID: <56C2574C.8050808@oracle.com> Please review this fix for simple cleanup in the way the -encoding option is handled in javac. JBS: https://bugs.openjdk.java.net/browse/JDK-8149772 Webrev: http://cr.openjdk.java.net/~jjg/8149772/webrev.00 -- Jon From jonathan.gibbons at oracle.com Tue Feb 16 00:21:56 2016 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Mon, 15 Feb 2016 16:21:56 -0800 Subject: JDK 9 RFR of JDK-6469562: Use compact notation to display annotation values In-Reply-To: <56C015BF.6090406@oracle.com> References: <56C015BF.6090406@oracle.com> Message-ID: <56C26BA4.5050804@oracle.com> Looks good to me. -- Jon On 02/13/2016 09:50 PM, joe darcy wrote: > Hello, > > Please review these changes to address > > JDK-6469562: Use compact notation to display annotation values > http://cr.openjdk.java.net/~darcy/6469562.0/ > > In brief, when it is not required the noisy "value=" portion of > annotation is now omitted in javadoc leading to a more concise display. > > (The to the files used to generated the javadoc are not strictly > necessary, but they do demonstrate that the "value=" is superfluous at > a source level.) > > Thanks, > > -Joe From jonathan.gibbons at oracle.com Tue Feb 16 03:37:31 2016 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Mon, 15 Feb 2016 19:37:31 -0800 Subject: RFR: 8149886: 16 windows tests broke with recent putback Message-ID: <56C2997B.6090401@oracle.com> Please review the following quick fix for a latent bug in javadoc, uncovered by recent change to use the nio.file API. The root cause is that you typically cannot create a Path from a string containing a URL; you may get an exception -- and will get one on Windows trying to create a Path for a string beginning http:.... The fix is to reverse two tests to ensure the string is not a URL JBS: https://bugs.openjdk.java.net/browse/JDK-8149886 Webrev: http://cr.openjdk.java.net/~jjg/8149886/webrev.00 -- Jon From sundararajan.athijegannathan at oracle.com Tue Feb 16 03:50:45 2016 From: sundararajan.athijegannathan at oracle.com (Sundararajan Athijegannathan) Date: Tue, 16 Feb 2016 09:20:45 +0530 Subject: RFR: 8149886: 16 windows tests broke with recent putback In-Reply-To: <56C2997B.6090401@oracle.com> References: <56C2997B.6090401@oracle.com> Message-ID: <56C29C95.7000502@oracle.com> Looks good. -Sundar On 2/16/2016 9:07 AM, Jonathan Gibbons wrote: > Please review the following quick fix for a latent bug in javadoc, > uncovered by recent change to use the nio.file API. > > The root cause is that you typically cannot create a Path from a > string containing a URL; you may get an exception -- and will get one > on Windows trying to create a Path for a string beginning http:.... > > The fix is to reverse two tests to ensure the string is not a URL > > JBS: https://bugs.openjdk.java.net/browse/JDK-8149886 > Webrev: http://cr.openjdk.java.net/~jjg/8149886/webrev.00 > > -- Jon From sven.reimers at gmail.com Tue Feb 16 14:08:17 2016 From: sven.reimers at gmail.com (Sven Reimers) Date: Tue, 16 Feb 2016 15:08:17 +0100 Subject: Compiler creates broken classfiles although errors are shown in output In-Reply-To: <56C220E5.4080104@oracle.com> References: <56C1EEFC.8010406@oracle.com> <56C220E5.4080104@oracle.com> Message-ID: Hi Jan, seems the problem is caused by using an annotation processor.. It seems sufficient to have an annotation processor doing nothing to trigger the behaviour. Will try to post an example, if you need one.. -Sven Am 15.02.2016 20:03 schrieb "Jan Lahoda" : > Hi Sven, > > I tried the example with: > $ javac -fullversion > javac full version "1.8.0_40-b25" > > And it produced: > $ javac Client.java > Client.java:7: error: cannot access I > new A().m(); > ^ > class file for p1.I not found > 1 error > > No classfile was written. > > With: > $ javac -fullversion > javac full version "1.7.0_45-b35" > > $ javac Client.java > > produced no errors, and written a (correct as far as I can tell) classfile > (equivalent to a classfile written when I.class is available). > > Do you have a testcase where javac produces an error, but writes an > (incorrect) classfile? > > Thanks, > Jan > > On 15.2.2016 17:02, Sven Reimers wrote: > >> There is an example in here >> >> >> http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-2156366.html >> >> Area: Tools / javac >> >> Synopsis >> >> Interfaces need to be present when compiling against their implementations >> >> Description >> >> When compiling a class against another class implementing an interface >> which is defined in yet another class file, such class file (where >> interface is defined) must be available in the class path used >> by javac during compilation. This is a new requirement as of JDK 8 - a >> failure to do so will result in a compilation error. >> >> Example: >> >> Client.java: >> >> import p1.A; >> >> class Client { >> >> void test() { >> >> new A.m(); >> >> } >> >> } >> >> p1/A.java: >> >> package p1; >> >> public class A implements I { >> >> public void m() { } >> >> } >> >> p1/I.java: >> >> package p1; >> >> public interface I { >> >> void m(); >> >> } >> >> If neither p1/I.java nor p1/I.class are available when compiling >> Client.java, the following error will be displayed: >> >> Client.java: error: cannot access I >> >> new A().m(); >> >> ^ >> >> class file for p1.I not found >> >> >> If this does not reproduce the problem, I will try to reduce our code >> sample >> >> Thanks >> >> Sven >> >> >> Hi Sven, >> >> Would you have a testcase on which this can be seen? >> >> Thanks, >> Jan >> >> On 15.2.2016 15:34, Sven Reimers wrote: >> >> > >> > Hi, >> > >> > I just ran intohttps://bugs.openjdk.java.net/browse/JDK-8145208 >> >> > >> > The main problem is not to fix the error, but our continuous >> > integration is not creating breaking builds, so the error can get >> > unnoticed into builds and fails at runtime. >> > >> > Any idea if this can be fixed in an upcoming jdk 8u release? >> > >> > Any idea how to make the build break in this case? >> > >> > Thanks for your help >> > >> > -Sven >> > >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From joe.darcy at oracle.com Wed Feb 17 01:00:59 2016 From: joe.darcy at oracle.com (Joseph D. Darcy) Date: Tue, 16 Feb 2016 17:00:59 -0800 Subject: JDK 9 RFR of JDK-6469562: Use compact notation to display annotation values In-Reply-To: <56C26BA4.5050804@oracle.com> References: <56C015BF.6090406@oracle.com> <56C26BA4.5050804@oracle.com> Message-ID: <56C3C64B.6030509@oracle.com> PS A follow-up on terminology, Alex pointed out to me off-list that the JLS refers to the structures under discussion as "single-element annotations": https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.7.3 -Joe On 2/15/2016 4:21 PM, Jonathan Gibbons wrote: > Looks good to me. > > -- Jon > > > On 02/13/2016 09:50 PM, joe darcy wrote: >> Hello, >> >> Please review these changes to address >> >> JDK-6469562: Use compact notation to display annotation values >> http://cr.openjdk.java.net/~darcy/6469562.0/ >> >> In brief, when it is not required the noisy "value=" portion of >> annotation is now omitted in javadoc leading to a more concise display. >> >> (The to the files used to generated the javadoc are not strictly >> necessary, but they do demonstrate that the "value=" is superfluous >> at a source level.) >> >> Thanks, >> >> -Joe > From archie at dellroad.org Wed Feb 17 16:40:04 2016 From: archie at dellroad.org (Archie Cobbs) Date: Wed, 17 Feb 2016 10:40:04 -0600 Subject: Question about submitting bugs Message-ID: Hi, I've got a meta-question regarding filing compiler bug reports... Compiler questions and possible bug reports are often posted to this list, but this list is obviously not meant to be a general triage area for bug reports from the entire Java community, so I'm hesitant to post occasional issues that crop up here. I've also noticed that the JDK bug submission form on http://bugreport.java.com/ doesn't seem to really work any more... I've submitted a couple of bug reports there lately but never heard anything back (example ). I have another one now but don't want it to be lost like the others. It also doesn't seem possible for mere mortals to create accounts on https://bugs.openjdk.java.net/ So what is the correct procedure for non-compiler-developers to productively report suspected compiler issues? Thanks, -Archie -- Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From jonathan.gibbons at oracle.com Wed Feb 17 16:56:13 2016 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Wed, 17 Feb 2016 08:56:13 -0800 Subject: Question about submitting bugs In-Reply-To: References: Message-ID: <56C4A62D.3080806@oracle.com> On 02/17/2016 08:40 AM, Archie Cobbs wrote: > Hi, > > I've got a meta-question regarding filing compiler bug reports... > > Compiler questions and possible bug reports are often posted to this > list, but this list is obviously not meant to be a general triage area > for bug reports from the entire Java community, so I'm hesitant to > post occasional issues that crop up here. > > I've also noticed that the JDK bug submission form on > http://bugreport.java.com/ doesn't seem to really work any more... > I've submitted a couple of bug reports there lately but never heard > anything back (example > ). > I have another one now but don't want it to be lost like the others. > > It also doesn't seem possible for mere mortals to create accounts on > https://bugs.openjdk.java.net/ > > So what is the correct procedure for non-compiler-developers to > productively report suspected compiler issues? > > Thanks, > -Archie > > -- > Archie L. Cobbs Archie, Thanks for asking. You are correct that this is not an area to help debug users programs. The more you have reasonable cause to suspect that javac may not be behaving correctly, (or could reasonably be improved) and the more you can produce evidence, such as reproducible test cases, to back up your claim, the more interested folk will be in general. Ideally, test cases should be small, and should be "just pure javac" -- meaning, so simple there's no need to involve any build tools, unless you believe they are an inherent part of the problem. If you file an issue on bugreport.java.com, and you don't hear back in a timely manner, you can try posting a reference here and we can help ensure the issue is migrated to bugs.openjdk.java.net. -- Jon -------------- next part -------------- An HTML attachment was scrubbed... URL: From archie at dellroad.org Wed Feb 17 17:12:48 2016 From: archie at dellroad.org (Archie Cobbs) Date: Wed, 17 Feb 2016 11:12:48 -0600 Subject: Question about submitting bugs In-Reply-To: <56C4A62D.3080806@oracle.com> References: <56C4A62D.3080806@oracle.com> Message-ID: Thanks Jon. Here are three suspected issues boiled down to simple test cases. Right now they are all failing with the 1.8.0_60 javac. I'm not up-to-date enough on current compiler development to know whether these are already fixed in jdk9 or not. Lambda generates IllegalAccessError at runtime: https://gist.github.com/archiecobbs/0e9a3e460c9581d13cb9 Compilation failure when overriding clone() http://stackoverflow.com/questions/33023332/why-doesnt-this-java-program-compile Compilation fails when assigning static final field using qualified name http://stackoverflow.com/questions/11705814/java-compile-error-depends-on-whether-static-variable-name-is-qualified Thanks, -Archie On Wed, Feb 17, 2016 at 10:56 AM, Jonathan Gibbons < jonathan.gibbons at oracle.com> wrote: > On 02/17/2016 08:40 AM, Archie Cobbs wrote: > > Hi, > > I've got a meta-question regarding filing compiler bug reports... > > Compiler questions and possible bug reports are often posted to this list, > but this list is obviously not meant to be a general triage area for bug > reports from the entire Java community, so I'm hesitant to post occasional > issues that crop up here. > > I've also noticed that the JDK bug submission form on > http://bugreport.java.com/ doesn't seem to really work any more... I've > submitted a couple of bug reports there lately but never heard anything > back (example > ). > I have another one now but don't want it to be lost like the others. > > It also doesn't seem possible for mere mortals to create accounts on > https://bugs.openjdk.java.net/ > > So what is the correct procedure for non-compiler-developers to > productively report suspected compiler issues? > > Thanks, > -Archie > > -- > Archie L. Cobbs > > > Archie, > > Thanks for asking. > > You are correct that this is not an area to help debug users programs. > The more you have reasonable cause to suspect that javac may not be > behaving correctly, (or could reasonably be improved) and the more you can > produce evidence, such as reproducible test cases, to back up your claim, > the more interested folk will be in general. Ideally, test cases should be > small, and should be "just pure javac" -- meaning, so simple there's no > need to involve any build tools, unless you believe they are an inherent > part of the problem. > > If you file an issue on bugreport.java.com, and you don't hear back in a > timely manner, you can try posting a reference here and we can help ensure > the issue is migrated to bugs.openjdk.java.net. > > -- Jon > -- Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From dalibor.topic at oracle.com Wed Feb 17 17:56:28 2016 From: dalibor.topic at oracle.com (dalibor topic) Date: Wed, 17 Feb 2016 18:56:28 +0100 Subject: Question about submitting bugs In-Reply-To: References: <56C4A62D.3080806@oracle.com> Message-ID: <56C4B44C.1040602@oracle.com> Archie - do you have the Java incident ids from the issues you have filed via bugreport.java.com? On 17.02.2016 18:12, Archie Cobbs wrote: > Thanks Jon. > > Here are three suspected issues boiled down to simple test cases. Right > now they are all failing with the 1.8.0_60 javac. I'm not up-to-date > enough on current compiler development to know whether these are already > fixed in jdk9 or not. > > Lambda generates IllegalAccessError at runtime: > https://gist.github.com/archiecobbs/0e9a3e460c9581d13cb9 > > Compilation failure when overriding clone() > http://stackoverflow.com/questions/33023332/why-doesnt-this-java-program-compile > > Compilation fails when assigning static final field using qualified name > http://stackoverflow.com/questions/11705814/java-compile-error-depends-on-whether-static-variable-name-is-qualified > > Thanks, > -Archie > > > On Wed, Feb 17, 2016 at 10:56 AM, Jonathan Gibbons > > wrote: > > On 02/17/2016 08:40 AM, Archie Cobbs wrote: >> Hi, >> >> I've got a meta-question regarding filing compiler bug reports... >> >> Compiler questions and possible bug reports are often posted to >> this list, but this list is obviously not meant to be a general >> triage area for bug reports from the entire Java community, so I'm >> hesitant to post occasional issues that crop up here. >> >> I've also noticed that the JDK bug submission form on >> http://bugreport.java.com/ doesn't seem to really work any more... >> I've submitted a couple of bug reports there lately but never >> heard anything back (example >> ). >> I have another one now but don't want it to be lost like the others. >> >> It also doesn't seem possible for mere mortals to create accounts >> on https://bugs.openjdk.java.net/ >> >> So what is the correct procedure for non-compiler-developers to >> productively report suspected compiler issues? >> >> Thanks, >> -Archie >> >> -- >> Archie L. Cobbs > > Archie, > > Thanks for asking. > > You are correct that this is not an area to help debug users > programs. The more you have reasonable cause to suspect that javac > may not be behaving correctly, (or could reasonably be improved) and > the more you can produce evidence, such as reproducible test cases, > to back up your claim, the more interested folk will be in general. > Ideally, test cases should be small, and should be "just pure javac" > -- meaning, so simple there's no need to involve any build tools, > unless you believe they are an inherent part of the problem. > > If you file an issue on bugreport.java.com > , and you don't hear back in a timely > manner, you can try posting a reference here and we can help ensure > the issue is migrated to bugs.openjdk.java.net > . > > -- Jon > > > > > -- > Archie L. Cobbs -- Dalibor Topic | Principal Product Manager Phone: +494089091214 | Mobile: +491737185961 ORACLE Deutschland B.V. & Co. KG | K?hneh?fe 5 | 22761 Hamburg ORACLE Deutschland B.V. & Co. KG Hauptverwaltung: Riesstr. 25, D-80992 M?nchen Registergericht: Amtsgericht M?nchen, HRA 95603 Komplement?rin: ORACLE Deutschland Verwaltung B.V. Hertogswetering 163/167, 3543 AS Utrecht, Niederlande Handelsregister der Handelskammer Midden-Niederlande, Nr. 30143697 Gesch?ftsf?hrer: Alexander van der Ven, Jan Schultheiss, Val Maher Oracle is committed to developing practices and products that help protect the environment From cushon at google.com Wed Feb 17 18:11:29 2016 From: cushon at google.com (Liam Miller-Cushon) Date: Wed, 17 Feb 2016 10:11:29 -0800 Subject: Question about submitting bugs In-Reply-To: <56C4A62D.3080806@oracle.com> References: <56C4A62D.3080806@oracle.com> Message-ID: On Wed, Feb 17, 2016 at 8:56 AM, Jonathan Gibbons < jonathan.gibbons at oracle.com> wrote: > If you file an issue on bugreport.java.com, and you don't hear back in a > timely manner, you can try posting a reference here and we can help ensure > the issue is migrated to bugs.openjdk.java.net. > Are you supposed to hear back from bugreport.java.com? For what it's worth, I have filed a handful of issues there that were triaged and migrated to bugs.openjdk.java.net, and I only received a response for one of them. Usually I wait a few weeks and look up the review ID using my favourite search engine. It'd be helpful if there was an automated notification, or if the bugs could be assigned stable IDs from the beginning. -------------- next part -------------- An HTML attachment was scrubbed... URL: From archie at dellroad.org Wed Feb 17 18:25:04 2016 From: archie at dellroad.org (Archie Cobbs) Date: Wed, 17 Feb 2016 12:25:04 -0600 Subject: Question about submitting bugs In-Reply-To: <56C4B44C.1040602@oracle.com> References: <56C4A62D.3080806@oracle.com> <56C4B44C.1040602@oracle.com> Message-ID: Hi Dalibor, On Wed, Feb 17, 2016 at 11:56 AM, dalibor topic wrote: > Archie - do you have the Java incident ids from the issues you have filed > via bugreport.java.com? > I can only find one of the "Review ID assigned" emails. It was for this issue: > Compilation failure when overriding clone() >> >> http://stackoverflow.com/questions/33023332/why-doesnt-this-java-program-compile >> > The review ID was JI-9025344, received in October 2015. Nothing else has been received as of now, though in this case it's only been 4 months (is that normal or slow?) I've filed several bugs over the years and have encountered all of the following scenarios: (a) No response received whatsoever (this has happened once or twice) (b) Review ID assigned and then no response (c) Bug ID assigned, but the link returns "bug is not available" Here are some examples of (b) and (c): Review ID JI-9025344 complier clone() override bug no response Review ID JI-9013936 Type.toString() bug no response Review ID 2311517 XMLEventWriter throws FileNotFoundException no response Bug ID 9009951 Compiler crash - AssertionError http://bugs.java.com/view_bug.do?bug_id=9009951 Bug is not available Bug ID 9001645 Javadoc omitting static final fields http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=9001645 Bug is not available Review ID 2687453 StAXResult generates invalid XML no response Review ID 9064468 Future javadoc clarification no response As you can see, the system makes it pretty hard to get any feedback about what's going on with the issue, or even to understand what expectations to have. Thanks, -Archie -- Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From steff.nicolas at gmail.com Wed Feb 17 18:53:02 2016 From: steff.nicolas at gmail.com (=?UTF-8?Q?St=C3=A9phane_NICOLAS?=) Date: Wed, 17 Feb 2016 10:53:02 -0800 Subject: Invoking code generated by an annotation processor In-Reply-To: <56BCDAFB.3040107@oracle.com> References: <56BB9250.20607@oracle.com> <56BBAAD5.7080807@oracle.com> <56BCDAFB.3040107@oracle.com> Message-ID: Hi Jon, Here is a summary about the bug, it should be enough for you to understand what is going wrong. Later, we will provide you with more details on an example you can use to reproduce the bug. Summary The problem is about static imports and invocation of generated code from main code. In our main code, we invoke some code that is generated by an annotation processor. This scenario is fully supported by javac. However, javac reports the calls to generated code as errors, when it should not, in a very specific scenario. In our main code, if we have an erroneous static import to a non existing member in an existing class, then the annotation processors are not triggered and all calls to the generated code will be marked, unduly, as errors. ? For us this is a very inconvenient bug because it floods developers with too many errors and it becomes very hard to pinpoint the only actual error in the code (the wrong static import statement). This error can actually be triggered very easily when refactoring. Please note that if we have an equally erroneous static import to a non existing class, then the bug doesn?t happen and only this static import will be marked as error. Extra thoughts We realized that we are kind of asking implicitly to distinguish static import errors to existing classes and non existing classes. But this may not be the right approach. It would not accommodate the hacky but possible scenario when you define class B extends A in your main code, and generate the class A. In that case, if A defines a public static field Foo, B would inherit it, and though B exists, B.Foo would not exist before annotation processing completes. The best approach for us seems to be to always run annotation processors even though there are some static imports problems and to resolve them after code generation = annotation processing. Static imports shouldn?t fail so fast.. Details We tested with the following version of Javac : - javac 1.7.0_79 - open JDK javac 1.7.0_79 - javac 1.8.0_60 here is our example : sorry, it will be a bit long to read, but it comes with a full explanation. We first give you easy repro steps and then an overview of the library. Javac issue and reproduction steps We have 3 branches to illustrate the problem : 1. Branch : Master https://github.com/f2prateek/dart/blob/master/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java This branch works fine, there is no compilation error. See below to compile it. To compile it quickly : 1. git clone git at github.com:f2prateek/dart.git 2. cd dart 3. mvn clean install 2. Branch : henson-error-linkage https://github.com/f2prateek/dart/blob/henson-error-linkage/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java import static com.f2prateek.dart.example.SampleActivity.UNEXISTING; is a static import to an existing class but a non existing member. It will reproduce the bug of javac, the compiler will return 2 errors. The call to generated code will also be marked as error : [INFO] ------------------------------------------------------------- [ERROR] COMPILATION ERROR : [INFO] ------------------------------------------------------------- [ERROR] /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] cannot find symbol symbol: static UNEXISTING location: class [ERROR] /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[39,21] cannot find symbol symbol: variable Henson location: class com.f2prateek.dart.example.MainActivity To compile it quickly : 1. git clone git at github.com:f2prateek/dart.git 2. cd dart 3. git checkout origin/henson-error-linkage 4. mvn clean install 3. Branch : henson-error-linkage-good https://github.com/f2prateek/dart/blob/henson-error-linkage-good/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java import static com.f2prateek.dart.example.UnExistingClass.UNEXISTING; is a static import to a non-existing class. It will not reproduce the bug of javac. We get only errors related to static import. (You can see that there is a minor glitch, errors are duplicated, but that is not our main concern). [INFO] ------------------------------------------------------------- [ERROR] COMPILATION ERROR : [INFO] ------------------------------------------------------------- [ERROR] /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,41] cannot find symbol symbol: class UnExistingClass location: package com.f2prateek.dart.example [ERROR] /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] static import only from classes and interfaces [ERROR] /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,41] cannot find symbol symbol: class UnExistingClass location: package com.f2prateek.dart.example [ERROR] /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] static import only from classes and interfaces To compile it quickly : 1. git clone git at github.com:f2prateek/dart.git 2. cd dart 3. git checkout origin/henson-error-linkage-good 4. mvn clean install Library overview Sample: https://github.com/f2prateek/dart/blob/master/dart-sample This project is the sample of our annotation processor based library for Android. Just to give you a little background, the lib has 2 parts : Dart & Henson. When creating an activity (~ a screen / JWindow) on Android, you can be passed a set of arguments via a Bundle. A bundle is a serialized container that contains serialized arguments. A bundle is like a map, parameters have a name (called key) and a value. The library is all about navigating from a source activity to a target activity and passing arguments via the bundle in a more convenient way. When using Dart & Henson together, we completely abstract the Bundle usage. ---- Dart allows to annotate fields members in a target screen and to assign values to these fields based on the content of the Bundle you receive : //from SampleActivity on GH public class SampleActivity { @InjectExtra(?key1?) String s1; //required key @InjectExtra(?key2?) @Nullable int i1; //optional key @Override protected void onCreate(Bundle bundle) { Dart.inject(this); // after this call the field s1 is assigned the value // of the entry key1 of the bundle // it is equivalent to : s = getIntent().getStringExtra(?key1?) // s1 is a required field in the bundle, whereas i1 is optional. // If an entry key2 is present, i2 will be assigned to it. } } ---- Henson allows to build the Bundle in the source activity to reach the given target activity. Henson creates a small DSL to build the Bundle, with a little state machine to emphasize the required and optional natures of parameters. //from MainActivity on GH public class MainActivity extends Activity { public void launchTargetActivity() { Intent intent = Henson.with(this) .gotoSampleActivity() // here is the generated DSL call .key1("foo") .key2(4) .build(); startActivity(intent); } } ---- Both Dart & Henson use annotation processing, which is a very common way to do things on Android, mostly for speed reasons (reflection is slow like hell, it is not JITed unlike on a standard JVM). Dart does not involve calling generated called directly, the code will be called via a little reflection. Henson is all about calling generated code. In the sample above, Henson class is generated and offers the DSL to build the bundle. Nice, no ? :) Thanks a lot guys, and sorry for this far too long but report, Daniel & Stephane 2016-02-11 11:03 GMT-08:00 Jonathan Gibbons : > St?phane, > > Can you reduce the test case down to a simple one(s) that you can post > here? > > -- Jon > > > > On 02/11/2016 10:44 AM, St?phane NICOLAS wrote: > > Hey Jon, > > we are going to create an example based on our annotation processor. It > will come in the form of a github repo, 1 branch that compiles fine, 2 > branches to illustrate different compile problems. Everything is mavenized > so it should work out of the box for you. We will also tell you what error > messages we have on the 2 failing branches, actual and expected behavior, > and provide you with our javac version(s). > > We hope this can help, thank you very much for your answers. > > St?phane > > > 2016-02-10 13:25 GMT-08:00 Jonathan Gibbons : > >> >> >> On 02/10/2016 12:59 PM, St?phane NICOLAS wrote: >> >> Thanks Jon for your fast answer. It's quite disappointing but it's better >> to know it early. >> It's sad to see how much effort we have put in our annotation processor, >> that it's a good idea but fails because of some general java ecosystem >> issue. >> >> Though, talking of the issue with team mates, it became more clear. Let >> me try to rephrase them more accurately than in my first mail. >> >> It seems to me that the design of javac could be improved to accommodate >> these 2 scenarios : >> >> 1. in case of a parse error (for instance a missing ; a bad brace, >> etc.) , javac should stop everything and report the actual problem, without >> getting any further into the analysis and not report any linkage problem >> (because javac would know that annotation processors ain't gonna run and >> that can create false positive about missing linkages. All other parse >> errors should be reported.). It seems to me this would be a healthy "fail >> early" design. >> >> >> This is the intent. Generally, javac is supposed to fail reasonably >> fast in general, and in that case in particular. If you are seeing >> otherwise, please provide a test case, including the version of javac you >> are using. >> >> >> >> >> 1. in case of a linkage error (for instance having a non existing >> import / calling a non existing method, etc.) then we should run the >> annotation processors on the partial AST. This mechanism is already in >> place to accomodate code generation. >> Then the linkage problems should be resolved and take into account >> the generated code, and only the remaining problems should show up. This is >> where javac actually fails because it reports all problems, including those >> that can be resolved by the code that is actually generated. Javac reports >> problem from a previous internal stage, it doesn't match the latest state >> it could reach internally where only 1 problem could not be resolved, the >> one that was not related to invoking generated code, it reports all >> linkages problem exactly like if no code was generated and no annotation >> processor had run. >> >> >> That is the intent. >> >> Really, there is no way for javac to support those 2 scenarios ? I got >> the strong feeling that it should but I understand my knowledge of javac >> has huge holes. I have been surprised by the complexity of the compiler's >> code. >> >> Thx again for your answer, it's been tremendously appreciated; there are >> just a handful people would could have been able to answer my question I am >> very happy someone actually did take the time to do it. >> >> Stephane >> >> 2016-02-10 11:41 GMT-08:00 Jonathan Gibbons >> : >> >>> >>> >>> On 02/10/2016 09:09 AM, St?phane NICOLAS wrote: >>> >>> I am facing a problem with Javac : I got a sweet annotation processor >>> that generates a DSL and I invoke the generated code from my main code. >>> >>> Everything works fine except when there is an error in my main code : if >>> I got a compile error in the main code, not related to the generated code, >>> like a missing comma (parsing problem), or calling an inexisting method >>> (linkage problem), then all calls to the annotation processor are marked as >>> errors by the compiler. >>> >>> Ideally I am just looking for a way to get rid of those error messages, >>> and keep only the original one that fails to compile. >>> >>> AFAIK, javac should support this scenario but it doesn't support it in a >>> very convenient way and I don't understand exactly why.. >>> >>> After reafing the javac code, open jdk 7 & 8, I realized that : >>> >>> Annotation processors are not called if there is any error to compile >>> the code. As the annotation processor are not triggered, the calls to >>> generated code get mark as an error. >>> >>> However, I could, by playing with shouldStopPolicy (+if error and if no >>> error) trigger the annotation processor and generate the code. But still, I >>> would receive in this case the errors related to calling the generated >>> code. Like if the generated code was not taken into account, like if I was >>> receiving errors from a previous compilation steps. >>> >>> I understand that javac parses the code, if it fails there, I will >>> receive only an error about the actual problem. And this is great. I just >>> want this error to show up, not any other, and it works fine. (Though I am >>> wondering if this is always true even I clean my build & generated files >>> before compiling) >>> >>> If there is a linkage problem in my original code, like calling an >>> non-existent method, javac will relax the error and trigger the annotation >>> processors and try to let them generate the code to see if the generated >>> code that satisfies the linkage problem. But then, though there is a state >>> in which javac will successfully satisfy all linkage related to generated >>> code but not the other linkage error, I get all calls to generated code >>> marked as errors. This is my problem. It looks like this internal state of >>> the compiler is never accessible and errors returned do not match this >>> state but more probably a previous internal state in which all linkage >>> errors are aggregated and returned. >>> >>> I think there is a solution to achieve what I want but I couldn't find >>> one. And the situation is bad : it may actually cancel the development of >>> the annotation processor lib I am developing. Just because the errors are >>> flooding the actual problem in the code. >>> >>> Would you have some time to advise me, and help me to make the lib work >>> as expected. >>> My goal is just to get only errors that are not related to calling >>> generated code if they are not those who fail the compilation. I don't want >>> to see my errors polluted by those calls if they are not responsible for >>> breaking the compilation. >>> >>> Stephane >>> >>> >>> Stephane, >>> >>> In general, there is no convenient solution for you here, because there >>> is no way for javac to predict what unresolved symbols may or may not be >>> generated by the annotation processor that has yet to be run. And in >>> general, it is not desirable to run annotation processors if the input >>> source code has significant errors, such as syntax errors. >>> >>> -- Jon >>> >> >> >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jonathan.gibbons at oracle.com Wed Feb 17 19:00:59 2016 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Wed, 17 Feb 2016 11:00:59 -0800 Subject: Invoking code generated by an annotation processor In-Reply-To: References: <56BB9250.20607@oracle.com> <56BBAAD5.7080807@oracle.com> <56BCDAFB.3040107@oracle.com> Message-ID: <56C4C36B.1090506@oracle.com> St?phane, Internally, during the period before anno processing, javac categorizes errors as recoverable or not, where "recoverable" means "could this error conceivably be fixed by running annotation processors, which may generate code." It may be that we have to examine the scenario you describe to decide if the error should be marked as recoverable. -- Jon On 02/17/2016 10:53 AM, St?phane NICOLAS wrote: > > Hi Jon, > > > Here is a summary about the bug, it should be enough for you to > understand what is going wrong. Later, we will provide you with more > details on an example you can use to reproduce the bug. > > > Summary > > > The problem is about static importsand invocation of generated > codefrom main code. > > > In our main code, we invoke some code that is generated by an > annotation processor. This scenario is fully supported by javac. > However, javac reports the calls to generated code as errors, when it > should not, in a very specific scenario. > > > In our main code, if we have an erroneous static import to a non > existing member in an existing class, then the annotation processors > are not triggered and all calls to the generated code will be marked, > unduly, as errors. > > ? For us this is a very inconvenient bug because it floods developers > with too many errors and it becomes very hard to pinpoint the only > actual error in the code (the wrong static import statement). This > error can actually be triggered very easily when refactoring. > > > Please note that if we have an equally erroneous static import to a > non existing class, then the bug doesn?t happen and only this static > import will be marked as error. > > > Extra thoughts > > We realized that we are kind of asking implicitly to distinguish > static import errors to existing classes and non existing classes. But > this may not be the right approach. It would not accommodate the hacky > but possible scenario when you define class B extends Ain your main > code, and generate the class A. In that case, if A defines a public > static field Foo, B would inherit it, and though B exists, B.Foo would > not exist before annotation processing completes. > The best approach for us seems to be to always run annotation > processors even though there are some static imports problems and to > resolve them after code generation = annotation processing. Static > imports shouldn?t fail so fast.. > > > Details > > > We tested with the following version of Javac : > > * > > javac 1.7.0_79 > > * > > open JDK javac 1.7.0_79 > > * > > javac 1.8.0_60 > > > here is our example : sorry, it will be a bit long to read, but it > comes with a full explanation. > > We first give you easy repro steps and then an overview of the library. > > > Javac issue and reproduction steps > > We have 3 branches to illustrate the problem : > > > 1. Branch : > Masterhttps://github.com/f2prateek/dart/blob/master/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java > This branch works fine, there is no compilation error. See below to > compile it. > > > To compile it quickly : > > 1. > > git clone git at github.com :f2prateek/dart.git > > 2. > > cd dart > > 3. > > mvn clean install > > > > 2. Branch : henson-error-linkage > > https://github.com/f2prateek/dart/blob/henson-error-linkage/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java > import staticcom.f2prateek.dart.example.SampleActivity.UNEXISTING; > is a static import to an existing class but a non existing member. It > will reproduce the bug of javac, the compiler will return 2 errors. > The call to generated code will also be marked as error : > > [INFO] ------------------------------------------------------------- > > [ERROR] COMPILATION ERROR : > > [INFO] ------------------------------------------------------------- > > [ERROR] > /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] > cannot find symbol > > symbol: static UNEXISTING > > location: class > > [ERROR] > /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[39,21] > cannot find symbol > > symbol: variable Henson > > location: class com.f2prateek.dart.example.MainActivity > > > To compile it quickly : > > 1. > > git clone git at github.com :f2prateek/dart.git > > 2. > > cd dart > > 3. > > git checkout origin/henson-error-linkage > > 4. > > mvn clean install > > > > 3. Branch : > henson-error-linkage-goodhttps://github.com/f2prateek/dart/blob/henson-error-linkage-good/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java > import staticcom.f2prateek.dart.example.UnExistingClass.UNEXISTING; > is a static import to a non-existing class. It will not reproduce the > bug of javac. We get only errors related to static import. (You can > see that there is a minor glitch, errors are duplicated, but that is > not our main concern). > > [INFO] ------------------------------------------------------------- > > [ERROR] COMPILATION ERROR : > > [INFO] ------------------------------------------------------------- > > [ERROR] > /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,41] > cannot find symbol > > symbol: class UnExistingClass > > location: package com.f2prateek.dart.example > > [ERROR] > /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] > static import only from classes and interfaces > > [ERROR] > /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,41] > cannot find symbol > > symbol: class UnExistingClass > > location: package com.f2prateek.dart.example > > [ERROR] > /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] > static import only from classes and interfaces > > > > To compile it quickly : > > 1. > > git clone git at github.com :f2prateek/dart.git > > 2. > > cd dart > > 3. > > git checkout origin/henson-error-linkage-good > > 4. > > mvn clean install > > > Library overview > > Sample: https://github.com/f2prateek/dart/blob/master/dart-sample > > This project is the sample of our annotation processor based library > for Android. > > Just to give you a little background, the lib has 2 parts : Dart& Henson. > > > When creating an activity (~ a screen / JWindow) on Android, you can > be passed a set of arguments via a Bundle. A bundle is a serialized > container that contains serialized arguments. > > A bundle is like a map, parameters have a name (called key) and a value. > > > The library is all about navigating from a source activity to a target > activity and passing arguments via the bundle in a more convenient > way. When using Dart & Henson together, we completely abstract the > Bundle usage. > > > ---- > > > Dartallows to annotate fields members in a target screen and to assign > values to these fields based on the content of the Bundle you receive : > > > //from SampleActivity on GH > > > public class SampleActivity { > > @InjectExtra(?key1?) String s1; //required key > > @InjectExtra(?key2?) @Nullable int i1; //optional key > > @Override > protected void onCreate(Bundle bundle) { > > Dart.inject(this); > > // after this call the field s1 is assigned the value > // of the entry key1 of the bundle > > // it is equivalent to : s = getIntent().getStringExtra(?key1?) > > // s1 is a required field in the bundle, whereas i1 is optional. > > // If an entry key2 is present, i2 will be assigned to it. > > } > > } > > ---- > > Henson allows to build the Bundle in the source activity to reach the > given target activity. Henson creates a small DSL to build the Bundle, > with a little state machine to emphasize the required and optional > natures of parameters. > > > //from MainActivity on GH > > > public class MainActivity extends Activity { > > public void launchTargetActivity() { > > Intent intent = Henson.with(this) > > .gotoSampleActivity() // here is the generated DSL call > > .key1("foo") > > .key2(4) > > .build(); > > > startActivity(intent); > > } > > } > > > ---- > > > Both Dart &Hensonuse annotation processing, which is a very common way > to do things on Android, mostly for speed reasons (reflection is slow > like hell, it is not JITed unlike on a standard JVM). Dart does not > involve calling generated called directly, the code will be called via > a little reflection. Henson is all about calling generated code. In > the sample above, Henson class is generated and offers the DSL to > build the bundle. > Nice, no ? :) > > > Thanks a lot guys, and sorry for this far too long but report, > > Daniel & Stephane > > > 2016-02-11 11:03 GMT-08:00 Jonathan Gibbons > >: > > St?phane, > > Can you reduce the test case down to a simple one(s) that you can > post here? > > -- Jon > > > > On 02/11/2016 10:44 AM, St?phane NICOLAS wrote: >> Hey Jon, >> >> we are going to create an example based on our annotation >> processor. It will come in the form of a github repo, 1 branch >> that compiles fine, 2 branches to illustrate different compile >> problems. Everything is mavenized so it should work out of the >> box for you. We will also tell you what error messages we have on >> the 2 failing branches, actual and expected behavior, and provide >> you with our javac version(s). >> >> We hope this can help, thank you very much for your answers. >> >> St?phane >> >> >> 2016-02-10 13:25 GMT-08:00 Jonathan Gibbons >> >: >> >> >> >> On 02/10/2016 12:59 PM, St?phane NICOLAS wrote: >>> Thanks Jon for your fast answer. It's quite disappointing >>> but it's better to know it early. >>> It's sad to see how much effort we have put in our >>> annotation processor, that it's a good idea but fails >>> because of some general java ecosystem issue. >>> >>> Though, talking of the issue with team mates, it became more >>> clear. Let me try to rephrase them more accurately than in >>> my first mail. >>> >>> It seems to me that the design of javac could be improved to >>> accommodate these 2 scenarios : >>> >>> 1. in case of a parse error (for instance a missing ; a bad >>> brace, etc.) , javac should stop everything and report >>> the actual problem, without getting any further into the >>> analysis and not report any linkage problem (because >>> javac would know that annotation processors ain't gonna >>> run and that can create false positive about missing >>> linkages. All other parse errors should be reported.). >>> It seems to me this would be a healthy "fail early" design. >>> >> >> This is the intent. Generally, javac is supposed to fail >> reasonably fast in general, and in that case in particular. >> If you are seeing otherwise, please provide a test case, >> including the version of javac you are using. >> >> >> >>> 1. in case of a linkage error (for instance having a non >>> existing import / calling a non existing method, etc.) >>> then we should run the annotation processors on the >>> partial AST. This mechanism is already in place to >>> accomodate code generation. >>> Then the linkage problems should be resolved and take >>> into account the generated code, and only the remaining >>> problems should show up. This is where javac actually >>> fails because it reports all problems, including those >>> that can be resolved by the code that is actually >>> generated. Javac reports problem from a previous >>> internal stage, it doesn't match the latest state it >>> could reach internally where only 1 problem could not be >>> resolved, the one that was not related to invoking >>> generated code, it reports all linkages problem exactly >>> like if no code was generated and no annotation >>> processor had run. >>> >> >> That is the intent. >> >>> Really, there is no way for javac to support those 2 >>> scenarios ? I got the strong feeling that it should but I >>> understand my knowledge of javac has huge holes. I have been >>> surprised by the complexity of the compiler's code. >>> >>> Thx again for your answer, it's been tremendously >>> appreciated; there are just a handful people would could >>> have been able to answer my question I am very happy someone >>> actually did take the time to do it. >>> >>> Stephane >>> >>> 2016-02-10 11:41 GMT-08:00 Jonathan Gibbons >>> >> >: >>> >>> >>> >>> On 02/10/2016 09:09 AM, St?phane NICOLAS wrote: >>>> I am facing a problem with Javac : I got a sweet >>>> annotation processor that generates a DSL and I invoke >>>> the generated code from my main code. >>>> >>>> Everything works fine except when there is an error in >>>> my main code : if I got a compile error in the main >>>> code, not related to the generated code, like a missing >>>> comma (parsing problem), or calling an inexisting >>>> method (linkage problem), then all calls to the >>>> annotation processor are marked as errors by the compiler. >>>> >>>> Ideally I am just looking for a way to get rid of those >>>> error messages, and keep only the original one that >>>> fails to compile. >>>> >>>> AFAIK, javac should support this scenario but it >>>> doesn't support it in a very convenient way and I don't >>>> understand exactly why.. >>>> >>>> After reafing the javac code, open jdk 7 & 8, I >>>> realized that : >>>> >>>> Annotation processors are not called if there is any >>>> error to compile the code. As the annotation processor >>>> are not triggered, the calls to generated code get mark >>>> as an error. >>>> >>>> However, I could, by playing with shouldStopPolicy (+if >>>> error and if no error) trigger the annotation processor >>>> and generate the code. But still, I would receive in >>>> this case the errors related to calling the generated >>>> code. Like if the generated code was not taken into >>>> account, like if I was receiving errors from a previous >>>> compilation steps. >>>> >>>> I understand that javac parses the code, if it fails >>>> there, I will receive only an error about the actual >>>> problem. And this is great. I just want this error to >>>> show up, not any other, and it works fine. (Though I am >>>> wondering if this is always true even I clean my build >>>> & generated files before compiling) >>>> >>>> If there is a linkage problem in my original code, like >>>> calling an non-existent method, javac will relax the >>>> error and trigger the annotation processors and try to >>>> let them generate the code to see if the generated code >>>> that satisfies the linkage problem. But then, though >>>> there is a state in which javac will successfully >>>> satisfy all linkage related to generated code but not >>>> the other linkage error, I get all calls to generated >>>> code marked as errors. This is my problem. It looks >>>> like this internal state of the compiler is never >>>> accessible and errors returned do not match this state >>>> but more probably a previous internal state in which >>>> all linkage errors are aggregated and returned. >>>> >>>> I think there is a solution to achieve what I want but >>>> I couldn't find one. And the situation is bad : it may >>>> actually cancel the development of the annotation >>>> processor lib I am developing. Just because the errors >>>> are flooding the actual problem in the code. >>>> >>>> Would you have some time to advise me, and help me to >>>> make the lib work as expected. >>>> My goal is just to get only errors that are not related >>>> to calling generated code if they are not those who >>>> fail the compilation. I don't want to see my errors >>>> polluted by those calls if they are not responsible for >>>> breaking the compilation. >>>> >>>> Stephane >>> >>> Stephane, >>> >>> In general, there is no convenient solution for you >>> here, because there is no way for javac to predict what >>> unresolved symbols may or may not be generated by the >>> annotation processor that has yet to be run. And in >>> general, it is not desirable to run annotation >>> processors if the input source code has significant >>> errors, such as syntax errors. >>> >>> -- Jon >>> >>> >> >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From steff.nicolas at gmail.com Wed Feb 17 19:36:56 2016 From: steff.nicolas at gmail.com (=?UTF-8?Q?St=C3=A9phane_NICOLAS?=) Date: Wed, 17 Feb 2016 11:36:56 -0800 Subject: Invoking code generated by an annotation processor In-Reply-To: <56C4C36B.1090506@oracle.com> References: <56BB9250.20607@oracle.com> <56BBAAD5.7080807@oracle.com> <56BCDAFB.3040107@oracle.com> <56C4C36B.1090506@oracle.com> Message-ID: Thx Jon. I would say there are 2 levels to answer this : 1) in case the error seems non recoverable, javac should just not list both recoverable and non recoverable errors. Only the non recoverable ones. We would be happy with that. 2) I am not sure this difference really holds in the case of "B extends A and A is generated", what would be marked as non recoverable is actually also recoverable. S. 2016-02-17 11:00 GMT-08:00 Jonathan Gibbons : > St?phane, > > Internally, during the period before anno processing, javac categorizes > errors as recoverable or not, where "recoverable" means "could this error > conceivably be fixed by running annotation processors, which may generate > code." > > It may be that we have to examine the scenario you describe to decide if > the error should be marked as recoverable. > > -- Jon > > > On 02/17/2016 10:53 AM, St?phane NICOLAS wrote: > > Hi Jon, > > Here is a summary about the bug, it should be enough for you to understand > what is going wrong. Later, we will provide you with more details on an > example you can use to reproduce the bug. > > Summary > > The problem is about static imports and invocation of generated code from > main code. > > In our main code, we invoke some code that is generated by an annotation > processor. This scenario is fully supported by javac. However, javac > reports the calls to generated code as errors, when it should not, in a > very specific scenario. > > In our main code, if we have an erroneous static import to a non existing > member in an existing class, then the annotation processors are not > triggered and all calls to the generated code will be marked, unduly, as > errors. > > ? For us this is a very inconvenient bug because it floods developers with > too many errors and it becomes very hard to pinpoint the only actual error > in the code (the wrong static import statement). This error can actually be > triggered very easily when refactoring. > > Please note that if we have an equally erroneous static import to a non > existing class, then the bug doesn?t happen and only this static import > will be marked as error. > > Extra thoughts > > We realized that we are kind of asking implicitly to distinguish static > import errors to existing classes and non existing classes. But this may > not be the right approach. It would not accommodate the hacky but possible > scenario when you define class B extends A in your main code, and > generate the class A. In that case, if A defines a public static field Foo, > B would inherit it, and though B exists, B.Foo would not exist before > annotation processing completes. > The best approach for us seems to be to always run annotation processors > even though there are some static imports problems and to resolve them > after code generation = annotation processing. Static imports shouldn?t > fail so fast.. > > Details > > We tested with the following version of Javac : > > - > > javac 1.7.0_79 > - > > open JDK javac 1.7.0_79 > - > > javac 1.8.0_60 > > > here is our example : sorry, it will be a bit long to read, but it comes > with a full explanation. > > We first give you easy repro steps and then an overview of the library. > > Javac issue and reproduction steps > > We have 3 branches to illustrate the problem : > > 1. Branch : Master > https://github.com/f2prateek/dart/blob/master/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java > This branch works fine, there is no compilation error. See below to > compile it. > > To compile it quickly : > > 1. > > git clone git at github.com:f2prateek/dart.git > 2. > > cd dart > 3. > > mvn clean install > > > > 2. Branch : henson-error-linkage > > > https://github.com/f2prateek/dart/blob/henson-error-linkage/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java > import static com.f2prateek.dart.example.SampleActivity.UNEXISTING; > is a static import to an existing class but a non existing member. It will > reproduce the bug of javac, the compiler will return 2 errors. The call to > generated code will also be marked as error : > > [INFO] ------------------------------------------------------------- > > [ERROR] COMPILATION ERROR : > > [INFO] ------------------------------------------------------------- > > [ERROR] > /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] > cannot find symbol > > symbol: static UNEXISTING > > location: class > > [ERROR] > /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[39,21] > cannot find symbol > > symbol: variable Henson > > location: class com.f2prateek.dart.example.MainActivity > > To compile it quickly : > > 1. > > git clone git at github.com:f2prateek/dart.git > 2. > > cd dart > 3. > > git checkout origin/henson-error-linkage > 4. > > mvn clean install > > > > 3. Branch : henson-error-linkage-good > https://github.com/f2prateek/dart/blob/henson-error-linkage-good/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java > import static com.f2prateek.dart.example.UnExistingClass.UNEXISTING; > is a static import to a non-existing class. It will not reproduce the bug > of javac. We get only errors related to static import. (You can see that > there is a minor glitch, errors are duplicated, but that is not our main > concern). > > [INFO] ------------------------------------------------------------- > > [ERROR] COMPILATION ERROR : > > [INFO] ------------------------------------------------------------- > > [ERROR] > /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,41] > cannot find symbol > > symbol: class UnExistingClass > > location: package com.f2prateek.dart.example > > [ERROR] > /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] > static import only from classes and interfaces > > [ERROR] > /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,41] > cannot find symbol > > symbol: class UnExistingClass > > location: package com.f2prateek.dart.example > > [ERROR] > /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] > static import only from classes and interfaces > > > To compile it quickly : > > 1. > > git clone git at github.com:f2prateek/dart.git > 2. > > cd dart > 3. > > git checkout origin/henson-error-linkage-good > 4. > > mvn clean install > > > Library overview > > Sample: https://github.com/f2prateek/dart/blob/master/dart-sample > > This project is the sample of our annotation processor based library for > Android. > > Just to give you a little background, the lib has 2 parts : Dart & Henson. > > > When creating an activity (~ a screen / JWindow) on Android, you can be > passed a set of arguments via a Bundle. A bundle is a serialized container > that contains serialized arguments. > > A bundle is like a map, parameters have a name (called key) and a value. > > The library is all about navigating from a source activity to a target > activity and passing arguments via the bundle in a more convenient way. > When using Dart & Henson together, we completely abstract the Bundle usage. > > ---- > > Dart allows to annotate fields members in a target screen and to assign > values to these fields based on the content of the Bundle you receive : > > //from SampleActivity on GH > > > public class SampleActivity { > > @InjectExtra(?key1?) String s1; //required key > > @InjectExtra(?key2?) @Nullable int i1; //optional key > > @Override > protected void onCreate(Bundle bundle) { > > Dart.inject(this); > > // after this call the field s1 is assigned the value > // of the entry key1 of the bundle > > // it is equivalent to : s = getIntent().getStringExtra(?key1?) > > // s1 is a required field in the bundle, whereas i1 is optional. > > // If an entry key2 is present, i2 will be assigned to it. > > } > > } > > ---- > > Henson allows to build the Bundle in the source activity to reach the > given target activity. Henson creates a small DSL to build the Bundle, with > a little state machine to emphasize the required and optional natures of > parameters. > > //from MainActivity on GH > > > public class MainActivity extends Activity { > > public void launchTargetActivity() { > > Intent intent = Henson.with(this) > > .gotoSampleActivity() // here is the generated DSL call > > .key1("foo") > > .key2(4) > > .build(); > > startActivity(intent); > > } > > } > > ---- > > Both Dart & Henson use annotation processing, which is a very common way > to do things on Android, mostly for speed reasons (reflection is slow like > hell, it is not JITed unlike on a standard JVM). Dart does not involve > calling generated called directly, the code will be called via a little > reflection. Henson is all about calling generated code. In the sample > above, Henson class is generated and offers the DSL to build the bundle. > Nice, no ? :) > > Thanks a lot guys, and sorry for this far too long but report, > > Daniel & Stephane > > 2016-02-11 11:03 GMT-08:00 Jonathan Gibbons : > >> St?phane, >> >> Can you reduce the test case down to a simple one(s) that you can post >> here? >> >> -- Jon >> >> >> >> On 02/11/2016 10:44 AM, St?phane NICOLAS wrote: >> >> Hey Jon, >> >> we are going to create an example based on our annotation processor. It >> will come in the form of a github repo, 1 branch that compiles fine, 2 >> branches to illustrate different compile problems. Everything is mavenized >> so it should work out of the box for you. We will also tell you what error >> messages we have on the 2 failing branches, actual and expected behavior, >> and provide you with our javac version(s). >> >> We hope this can help, thank you very much for your answers. >> >> St?phane >> >> >> 2016-02-10 13:25 GMT-08:00 Jonathan Gibbons >> : >> >>> >>> >>> On 02/10/2016 12:59 PM, St?phane NICOLAS wrote: >>> >>> Thanks Jon for your fast answer. It's quite disappointing but it's >>> better to know it early. >>> It's sad to see how much effort we have put in our annotation processor, >>> that it's a good idea but fails because of some general java ecosystem >>> issue. >>> >>> Though, talking of the issue with team mates, it became more clear. Let >>> me try to rephrase them more accurately than in my first mail. >>> >>> It seems to me that the design of javac could be improved to accommodate >>> these 2 scenarios : >>> >>> 1. in case of a parse error (for instance a missing ; a bad brace, >>> etc.) , javac should stop everything and report the actual problem, without >>> getting any further into the analysis and not report any linkage problem >>> (because javac would know that annotation processors ain't gonna run and >>> that can create false positive about missing linkages. All other parse >>> errors should be reported.). It seems to me this would be a healthy "fail >>> early" design. >>> >>> >>> This is the intent. Generally, javac is supposed to fail reasonably >>> fast in general, and in that case in particular. If you are seeing >>> otherwise, please provide a test case, including the version of javac you >>> are using. >>> >>> >>> >>> >>> 1. in case of a linkage error (for instance having a non existing >>> import / calling a non existing method, etc.) then we should run the >>> annotation processors on the partial AST. This mechanism is already in >>> place to accomodate code generation. >>> Then the linkage problems should be resolved and take into account >>> the generated code, and only the remaining problems should show up. This is >>> where javac actually fails because it reports all problems, including those >>> that can be resolved by the code that is actually generated. Javac reports >>> problem from a previous internal stage, it doesn't match the latest state >>> it could reach internally where only 1 problem could not be resolved, the >>> one that was not related to invoking generated code, it reports all >>> linkages problem exactly like if no code was generated and no annotation >>> processor had run. >>> >>> >>> That is the intent. >>> >>> Really, there is no way for javac to support those 2 scenarios ? I got >>> the strong feeling that it should but I understand my knowledge of javac >>> has huge holes. I have been surprised by the complexity of the compiler's >>> code. >>> >>> Thx again for your answer, it's been tremendously appreciated; there are >>> just a handful people would could have been able to answer my question I am >>> very happy someone actually did take the time to do it. >>> >>> Stephane >>> >>> 2016-02-10 11:41 GMT-08:00 Jonathan Gibbons >> >: >>> >>>> >>>> >>>> On 02/10/2016 09:09 AM, St?phane NICOLAS wrote: >>>> >>>> I am facing a problem with Javac : I got a sweet annotation processor >>>> that generates a DSL and I invoke the generated code from my main code. >>>> >>>> Everything works fine except when there is an error in my main code : >>>> if I got a compile error in the main code, not related to the generated >>>> code, like a missing comma (parsing problem), or calling an inexisting >>>> method (linkage problem), then all calls to the annotation processor are >>>> marked as errors by the compiler. >>>> >>>> Ideally I am just looking for a way to get rid of those error messages, >>>> and keep only the original one that fails to compile. >>>> >>>> AFAIK, javac should support this scenario but it doesn't support it in >>>> a very convenient way and I don't understand exactly why.. >>>> >>>> After reafing the javac code, open jdk 7 & 8, I realized that : >>>> >>>> Annotation processors are not called if there is any error to compile >>>> the code. As the annotation processor are not triggered, the calls to >>>> generated code get mark as an error. >>>> >>>> However, I could, by playing with shouldStopPolicy (+if error and if no >>>> error) trigger the annotation processor and generate the code. But still, I >>>> would receive in this case the errors related to calling the generated >>>> code. Like if the generated code was not taken into account, like if I was >>>> receiving errors from a previous compilation steps. >>>> >>>> I understand that javac parses the code, if it fails there, I will >>>> receive only an error about the actual problem. And this is great. I just >>>> want this error to show up, not any other, and it works fine. (Though I am >>>> wondering if this is always true even I clean my build & generated files >>>> before compiling) >>>> >>>> If there is a linkage problem in my original code, like calling an >>>> non-existent method, javac will relax the error and trigger the annotation >>>> processors and try to let them generate the code to see if the generated >>>> code that satisfies the linkage problem. But then, though there is a state >>>> in which javac will successfully satisfy all linkage related to generated >>>> code but not the other linkage error, I get all calls to generated code >>>> marked as errors. This is my problem. It looks like this internal state of >>>> the compiler is never accessible and errors returned do not match this >>>> state but more probably a previous internal state in which all linkage >>>> errors are aggregated and returned. >>>> >>>> I think there is a solution to achieve what I want but I couldn't find >>>> one. And the situation is bad : it may actually cancel the development of >>>> the annotation processor lib I am developing. Just because the errors are >>>> flooding the actual problem in the code. >>>> >>>> Would you have some time to advise me, and help me to make the lib work >>>> as expected. >>>> My goal is just to get only errors that are not related to calling >>>> generated code if they are not those who fail the compilation. I don't want >>>> to see my errors polluted by those calls if they are not responsible for >>>> breaking the compilation. >>>> >>>> Stephane >>>> >>>> >>>> Stephane, >>>> >>>> In general, there is no convenient solution for you here, because there >>>> is no way for javac to predict what unresolved symbols may or may not be >>>> generated by the annotation processor that has yet to be run. And in >>>> general, it is not desirable to run annotation processors if the input >>>> source code has significant errors, such as syntax errors. >>>> >>>> -- Jon >>>> >>> >>> >>> >> >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jonathan.gibbons at oracle.com Wed Feb 17 19:45:51 2016 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Wed, 17 Feb 2016 11:45:51 -0800 Subject: Invoking code generated by an annotation processor In-Reply-To: References: <56BB9250.20607@oracle.com> <56BBAAD5.7080807@oracle.com> <56BCDAFB.3040107@oracle.com> <56C4C36B.1090506@oracle.com> Message-ID: <56C4CDEF.8020505@oracle.com> On 02/17/2016 11:36 AM, St?phane NICOLAS wrote: > Thx Jon. > > I would say there are 2 levels to answer this : > 1) in case the error seems non recoverable, javac should just not list > both recoverable and non recoverable errors. Only the non recoverable > ones. > We would be happy with that. We could *maybe* prioritize the messages, but I think it would be wrong to only show non-recoverable errors. Just because an error is recoverable doesn't mean that an anno processor will generate code to make the error go away. > 2) I am not sure this difference really holds in the case of "B > extends A and A is generated", what would be marked as non recoverable > is actually also recoverable. Generally, recoverable errors are those of the form "name not found", in the sense that "name" could maybe be found if an anno processor generates the code. -- Jon > > S. > > 2016-02-17 11:00 GMT-08:00 Jonathan Gibbons > >: > > St?phane, > > Internally, during the period before anno processing, javac > categorizes errors as recoverable or not, where "recoverable" > means "could this error conceivably be fixed by running annotation > processors, which may generate code." > > It may be that we have to examine the scenario you describe to > decide if the error should be marked as recoverable. > > -- Jon > > > On 02/17/2016 10:53 AM, St?phane NICOLAS wrote: >> >> Hi Jon, >> >> >> Here is a summary about the bug, it should be enough for you to >> understand what is going wrong. Later, we will provide you with >> more details on an example you can use to reproduce the bug. >> >> >> Summary >> >> >> The problem is about static importsand invocation of generated >> codefrom main code. >> >> >> In our main code, we invoke some code that is generated by an >> annotation processor. This scenario is fully supported by javac. >> However, javac reports the calls to generated code as errors, >> when it should not, in a very specific scenario. >> >> >> In our main code, if we have an erroneous static import to a non >> existing member in an existing class, then the annotation >> processors are not triggered and all calls to the generated code >> will be marked, unduly, as errors. >> >> ? For us this is a very inconvenient bug because it floods >> developers with too many errors and it becomes very hard to >> pinpoint the only actual error in the code (the wrong static >> import statement). This error can actually be triggered very >> easily when refactoring. >> >> >> Please note that if we have an equally erroneous static import to >> a non existing class, then the bug doesn?t happen and only this >> static import will be marked as error. >> >> >> Extra thoughts >> >> We realized that we are kind of asking implicitly to distinguish >> static import errors to existing classes and non existing >> classes. But this may not be the right approach. It would not >> accommodate the hacky but possible scenario when you define class >> B extends Ain your main code, and generate the class A. In that >> case, if A defines a public static field Foo, B would inherit it, >> and though B exists, B.Foo would not exist before annotation >> processing completes. >> The best approach for us seems to be to always run annotation >> processors even though there are some static imports problems and >> to resolve them after code generation = annotation processing. >> Static imports shouldn?t fail so fast.. >> >> >> Details >> >> >> We tested with the following version of Javac : >> >> * >> >> javac 1.7.0_79 >> >> * >> >> open JDK javac 1.7.0_79 >> >> * >> >> javac 1.8.0_60 >> >> >> here is our example : sorry, it will be a bit long to read, but >> it comes with a full explanation. >> >> We first give you easy repro steps and then an overview of the >> library. >> >> >> Javac issue and reproduction steps >> >> We have 3 branches to illustrate the problem : >> >> >> 1. Branch : >> Masterhttps://github.com/f2prateek/dart/blob/master/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java >> This branch works fine, there is no compilation error. See below >> to compile it. >> >> >> To compile it quickly : >> >> 1. >> >> git clone git at github.com >> :f2prateek/dart.git >> >> 2. >> >> cd dart >> >> 3. >> >> mvn clean install >> >> >> >> 2. Branch : henson-error-linkage >> >> https://github.com/f2prateek/dart/blob/henson-error-linkage/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java >> import staticcom.f2prateek.dart.example.SampleActivity.UNEXISTING; >> is a static import to an existing class but a non existing >> member. It will reproduce the bug of javac, the compiler will >> return 2 errors. The call to generated code will also be marked >> as error : >> >> [INFO] ------------------------------------------------------------- >> >> [ERROR] COMPILATION ERROR : >> >> [INFO] ------------------------------------------------------------- >> >> [ERROR] >> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] >> cannot find symbol >> >> symbol: static UNEXISTING >> >> location: class >> >> [ERROR] >> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[39,21] >> cannot find symbol >> >> symbol: variable Henson >> >> location: class com.f2prateek.dart.example.MainActivity >> >> >> To compile it quickly : >> >> 1. >> >> git clone git at github.com >> :f2prateek/dart.git >> >> 2. >> >> cd dart >> >> 3. >> >> git checkout origin/henson-error-linkage >> >> 4. >> >> mvn clean install >> >> >> >> 3. Branch : >> henson-error-linkage-goodhttps://github.com/f2prateek/dart/blob/henson-error-linkage-good/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java >> import staticcom.f2prateek.dart.example.UnExistingClass.UNEXISTING; >> is a static import to a non-existing class. It will not reproduce >> the bug of javac. We get only errors related to static import. >> (You can see that there is a minor glitch, errors are duplicated, >> but that is not our main concern). >> >> [INFO] ------------------------------------------------------------- >> >> [ERROR] COMPILATION ERROR : >> >> [INFO] ------------------------------------------------------------- >> >> [ERROR] >> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,41] >> cannot find symbol >> >> symbol: class UnExistingClass >> >> location: package com.f2prateek.dart.example >> >> [ERROR] >> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] >> static import only from classes and interfaces >> >> [ERROR] >> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,41] >> cannot find symbol >> >> symbol: class UnExistingClass >> >> location: package com.f2prateek.dart.example >> >> [ERROR] >> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] >> static import only from classes and interfaces >> >> >> >> To compile it quickly : >> >> 1. >> >> git clone git at github.com >> :f2prateek/dart.git >> >> 2. >> >> cd dart >> >> 3. >> >> git checkout origin/henson-error-linkage-good >> >> 4. >> >> mvn clean install >> >> >> Library overview >> >> Sample: https://github.com/f2prateek/dart/blob/master/dart-sample >> >> This project is the sample of our annotation processor based >> library for Android. >> >> Just to give you a little background, the lib has 2 parts : Dart& >> Henson. >> >> >> When creating an activity (~ a screen / JWindow) on Android, you >> can be passed a set of arguments via a Bundle. A bundle is a >> serialized container that contains serialized arguments. >> >> A bundle is like a map, parameters have a name (called key) and a >> value. >> >> >> The library is all about navigating from a source activity to a >> target activity and passing arguments via the bundle in a more >> convenient way. When using Dart & Henson together, we completely >> abstract the Bundle usage. >> >> >> ---- >> >> >> Dartallows to annotate fields members in a target screen and to >> assign values to these fields based on the content of the Bundle >> you receive : >> >> >> //from SampleActivity on GH >> >> >> public class SampleActivity { >> >> @InjectExtra(?key1?) String s1; //required key >> >> @InjectExtra(?key2?) @Nullable int i1; //optional key >> >> @Override >> protected void onCreate(Bundle bundle) { >> >> Dart.inject(this); >> >> // after this call the field s1 is assigned the value >> // of the entry key1 of the bundle >> >> // it is equivalent to : s = getIntent().getStringExtra(?key1?) >> >> // s1 is a required field in the bundle, whereas i1 is >> optional. >> >> // If an entry key2 is present, i2 will be assigned to it. >> >> } >> >> } >> >> ---- >> >> Henson allows to build the Bundle in the source activity to reach >> the given target activity. Henson creates a small DSL to build >> the Bundle, with a little state machine to emphasize the required >> and optional natures of parameters. >> >> >> //from MainActivity on GH >> >> >> public class MainActivity extends Activity { >> >> public void launchTargetActivity() { >> >> Intent intent = Henson.with(this) >> >> .gotoSampleActivity() // here is the generated DSL call >> >> .key1("foo") >> >> .key2(4) >> >> .build(); >> >> >> startActivity(intent); >> >> } >> >> } >> >> >> ---- >> >> >> Both Dart &Hensonuse annotation processing, which is a very >> common way to do things on Android, mostly for speed reasons >> (reflection is slow like hell, it is not JITed unlike on a >> standard JVM). Dart does not involve calling generated called >> directly, the code will be called via a little reflection. Henson >> is all about calling generated code. In the sample above, Henson >> class is generated and offers the DSL to build the bundle. >> Nice, no ? :) >> >> >> Thanks a lot guys, and sorry for this far too long but report, >> >> Daniel & Stephane >> >> >> 2016-02-11 11:03 GMT-08:00 Jonathan Gibbons >> >: >> >> St?phane, >> >> Can you reduce the test case down to a simple one(s) that you >> can post here? >> >> -- Jon >> >> >> >> On 02/11/2016 10:44 AM, St?phane NICOLAS wrote: >>> Hey Jon, >>> >>> we are going to create an example based on our annotation >>> processor. It will come in the form of a github repo, 1 >>> branch that compiles fine, 2 branches to illustrate >>> different compile problems. Everything is mavenized so it >>> should work out of the box for you. We will also tell you >>> what error messages we have on the 2 failing branches, >>> actual and expected behavior, and provide you with our javac >>> version(s). >>> >>> We hope this can help, thank you very much for your answers. >>> >>> St?phane >>> >>> >>> 2016-02-10 13:25 GMT-08:00 Jonathan Gibbons >>> >> >: >>> >>> >>> >>> On 02/10/2016 12:59 PM, St?phane NICOLAS wrote: >>>> Thanks Jon for your fast answer. It's quite >>>> disappointing but it's better to know it early. >>>> It's sad to see how much effort we have put in our >>>> annotation processor, that it's a good idea but fails >>>> because of some general java ecosystem issue. >>>> >>>> Though, talking of the issue with team mates, it became >>>> more clear. Let me try to rephrase them more accurately >>>> than in my first mail. >>>> >>>> It seems to me that the design of javac could be >>>> improved to accommodate these 2 scenarios : >>>> >>>> 1. in case of a parse error (for instance a missing ; >>>> a bad brace, etc.) , javac should stop everything >>>> and report the actual problem, without getting any >>>> further into the analysis and not report any >>>> linkage problem (because javac would know that >>>> annotation processors ain't gonna run and that can >>>> create false positive about missing linkages. All >>>> other parse errors should be reported.). It seems >>>> to me this would be a healthy "fail early" design. >>>> >>> >>> This is the intent. Generally, javac is supposed to fail >>> reasonably fast in general, and in that case in >>> particular. If you are seeing otherwise, please >>> provide a test case, including the version of javac you >>> are using. >>> >>> >>> >>>> 1. in case of a linkage error (for instance having a >>>> non existing import / calling a non existing >>>> method, etc.) then we should run the annotation >>>> processors on the partial AST. This mechanism is >>>> already in place to accomodate code generation. >>>> Then the linkage problems should be resolved and >>>> take into account the generated code, and only the >>>> remaining problems should show up. This is where >>>> javac actually fails because it reports all >>>> problems, including those that can be resolved by >>>> the code that is actually generated. Javac reports >>>> problem from a previous internal stage, it doesn't >>>> match the latest state it could reach internally >>>> where only 1 problem could not be resolved, the one >>>> that was not related to invoking generated code, it >>>> reports all linkages problem exactly like if no >>>> code was generated and no annotation processor had run. >>>> >>> >>> That is the intent. >>> >>>> Really, there is no way for javac to support those 2 >>>> scenarios ? I got the strong feeling that it should but >>>> I understand my knowledge of javac has huge holes. I >>>> have been surprised by the complexity of the compiler's >>>> code. >>>> >>>> Thx again for your answer, it's been tremendously >>>> appreciated; there are just a handful people would >>>> could have been able to answer my question I am very >>>> happy someone actually did take the time to do it. >>>> >>>> Stephane >>>> >>>> 2016-02-10 11:41 GMT-08:00 Jonathan Gibbons >>>> >>> >: >>>> >>>> >>>> >>>> On 02/10/2016 09:09 AM, St?phane NICOLAS wrote: >>>>> I am facing a problem with Javac : I got a sweet >>>>> annotation processor that generates a DSL and I >>>>> invoke the generated code from my main code. >>>>> >>>>> Everything works fine except when there is an >>>>> error in my main code : if I got a compile error >>>>> in the main code, not related to the generated >>>>> code, like a missing comma (parsing problem), or >>>>> calling an inexisting method (linkage problem), >>>>> then all calls to the annotation processor are >>>>> marked as errors by the compiler. >>>>> >>>>> Ideally I am just looking for a way to get rid of >>>>> those error messages, and keep only the original >>>>> one that fails to compile. >>>>> >>>>> AFAIK, javac should support this scenario but it >>>>> doesn't support it in a very convenient way and I >>>>> don't understand exactly why.. >>>>> >>>>> After reafing the javac code, open jdk 7 & 8, I >>>>> realized that : >>>>> >>>>> Annotation processors are not called if there is >>>>> any error to compile the code. As the annotation >>>>> processor are not triggered, the calls to >>>>> generated code get mark as an error. >>>>> >>>>> However, I could, by playing with shouldStopPolicy >>>>> (+if error and if no error) trigger the annotation >>>>> processor and generate the code. But still, I >>>>> would receive in this case the errors related to >>>>> calling the generated code. Like if the generated >>>>> code was not taken into account, like if I was >>>>> receiving errors from a previous compilation steps. >>>>> >>>>> I understand that javac parses the code, if it >>>>> fails there, I will receive only an error about >>>>> the actual problem. And this is great. I just want >>>>> this error to show up, not any other, and it works >>>>> fine. (Though I am wondering if this is always >>>>> true even I clean my build & generated files >>>>> before compiling) >>>>> >>>>> If there is a linkage problem in my original code, >>>>> like calling an non-existent method, javac will >>>>> relax the error and trigger the annotation >>>>> processors and try to let them generate the code >>>>> to see if the generated code that satisfies the >>>>> linkage problem. But then, though there is a state >>>>> in which javac will successfully satisfy all >>>>> linkage related to generated code but not the >>>>> other linkage error, I get all calls to generated >>>>> code marked as errors. This is my problem. It >>>>> looks like this internal state of the compiler is >>>>> never accessible and errors returned do not match >>>>> this state but more probably a previous internal >>>>> state in which all linkage errors are aggregated >>>>> and returned. >>>>> >>>>> I think there is a solution to achieve what I want >>>>> but I couldn't find one. And the situation is bad >>>>> : it may actually cancel the development of the >>>>> annotation processor lib I am developing. Just >>>>> because the errors are flooding the actual problem >>>>> in the code. >>>>> >>>>> Would you have some time to advise me, and help me >>>>> to make the lib work as expected. >>>>> My goal is just to get only errors that are not >>>>> related to calling generated code if they are not >>>>> those who fail the compilation. I don't want to >>>>> see my errors polluted by those calls if they are >>>>> not responsible for breaking the compilation. >>>>> >>>>> Stephane >>>> >>>> Stephane, >>>> >>>> In general, there is no convenient solution for you >>>> here, because there is no way for javac to predict >>>> what unresolved symbols may or may not be generated >>>> by the annotation processor that has yet to be run. >>>> And in general, it is not desirable to run >>>> annotation processors if the input source code has >>>> significant errors, such as syntax errors. >>>> >>>> -- Jon >>>> >>>> >>> >>> >> >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From steff.nicolas at gmail.com Wed Feb 17 20:21:21 2016 From: steff.nicolas at gmail.com (=?UTF-8?Q?St=C3=A9phane_NICOLAS?=) Date: Wed, 17 Feb 2016 12:21:21 -0800 Subject: Invoking code generated by an annotation processor In-Reply-To: <56C4CDEF.8020505@oracle.com> References: <56BB9250.20607@oracle.com> <56BBAAD5.7080807@oracle.com> <56BCDAFB.3040107@oracle.com> <56C4C36B.1090506@oracle.com> <56C4CDEF.8020505@oracle.com> Message-ID: 2016-02-17 11:45 GMT-08:00 Jonathan Gibbons : > > > On 02/17/2016 11:36 AM, St?phane NICOLAS wrote: > > Thx Jon. > > I would say there are 2 levels to answer this : > 1) in case the error seems non recoverable, javac should just not list > both recoverable and non recoverable errors. Only the non recoverable ones. > We would be happy with that. > > > We could *maybe* prioritize the messages, but I think it would be wrong to > only show non-recoverable errors. Just because an error is recoverable > doesn't mean that an anno processor will generate code to make the error go > away. > > No, it doesn't mean that, but in our case it is what happens and as the > annotation processor is not given the chance to run and resolve those > recoverable errors, they should not be listed. > > 2) I am not sure this difference really holds in the case of "B extends A > and A is generated", what would be marked as non recoverable is actually > also recoverable. > > > Generally, recoverable errors are those of the form "name not found", in > the sense that "name" could maybe be found if an anno processor generates > the code. > So we were wrong in our understanding as we understood that they were different levels of "names not found" errors. It looks like when the class is found and a field not found, the error is ranked as non-recoverable. But really this case is further to ours, we just added an extra thought so that bug resolution takes into account the scenario, but it's not our main concern. > > > -- Jon > > > > > S. > > 2016-02-17 11:00 GMT-08:00 Jonathan Gibbons : > >> St?phane, >> >> Internally, during the period before anno processing, javac categorizes >> errors as recoverable or not, where "recoverable" means "could this error >> conceivably be fixed by running annotation processors, which may generate >> code." >> >> It may be that we have to examine the scenario you describe to decide if >> the error should be marked as recoverable. >> >> -- Jon >> >> >> On 02/17/2016 10:53 AM, St?phane NICOLAS wrote: >> >> Hi Jon, >> >> Here is a summary about the bug, it should be enough for you to >> understand what is going wrong. Later, we will provide you with more >> details on an example you can use to reproduce the bug. >> >> Summary >> >> The problem is about static imports and invocation of generated code >> from main code. >> >> In our main code, we invoke some code that is generated by an annotation >> processor. This scenario is fully supported by javac. However, javac >> reports the calls to generated code as errors, when it should not, in a >> very specific scenario. >> >> In our main code, if we have an erroneous static import to a non existing >> member in an existing class, then the annotation processors are not >> triggered and all calls to the generated code will be marked, unduly, as >> errors. >> >> ? For us this is a very inconvenient bug because it floods developers >> with too many errors and it becomes very hard to pinpoint the only actual >> error in the code (the wrong static import statement). This error can >> actually be triggered very easily when refactoring. >> >> Please note that if we have an equally erroneous static import to a non >> existing class, then the bug doesn?t happen and only this static import >> will be marked as error. >> >> Extra thoughts >> >> We realized that we are kind of asking implicitly to distinguish static >> import errors to existing classes and non existing classes. But this may >> not be the right approach. It would not accommodate the hacky but possible >> scenario when you define class B extends A in your main code, and >> generate the class A. In that case, if A defines a public static field Foo, >> B would inherit it, and though B exists, B.Foo would not exist before >> annotation processing completes. >> The best approach for us seems to be to always run annotation processors >> even though there are some static imports problems and to resolve them >> after code generation = annotation processing. Static imports shouldn?t >> fail so fast.. >> >> Details >> >> We tested with the following version of Javac : >> >> - >> >> javac 1.7.0_79 >> - >> >> open JDK javac 1.7.0_79 >> - >> >> javac 1.8.0_60 >> >> >> here is our example : sorry, it will be a bit long to read, but it comes >> with a full explanation. >> >> We first give you easy repro steps and then an overview of the library. >> >> Javac issue and reproduction steps >> >> We have 3 branches to illustrate the problem : >> >> 1. Branch : Master >> https://github.com/f2prateek/dart/blob/master/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java >> This branch works fine, there is no compilation error. See below to >> compile it. >> >> To compile it quickly : >> >> 1. >> >> git clone git at github.com:f2prateek/dart.git >> 2. >> >> cd dart >> 3. >> >> mvn clean install >> >> >> >> 2. Branch : henson-error-linkage >> >> >> https://github.com/f2prateek/dart/blob/henson-error-linkage/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java >> import static com.f2prateek.dart.example.SampleActivity.UNEXISTING; >> is a static import to an existing class but a non existing member. It >> will reproduce the bug of javac, the compiler will return 2 errors. The >> call to generated code will also be marked as error : >> >> [INFO] ------------------------------------------------------------- >> >> [ERROR] COMPILATION ERROR : >> >> [INFO] ------------------------------------------------------------- >> >> [ERROR] >> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] >> cannot find symbol >> >> symbol: static UNEXISTING >> >> location: class >> >> [ERROR] >> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[39,21] >> cannot find symbol >> >> symbol: variable Henson >> >> location: class com.f2prateek.dart.example.MainActivity >> >> To compile it quickly : >> >> 1. >> >> git clone git at github.com:f2prateek/dart.git >> 2. >> >> cd dart >> 3. >> >> git checkout origin/henson-error-linkage >> 4. >> >> mvn clean install >> >> >> >> 3. Branch : henson-error-linkage-good >> https://github.com/f2prateek/dart/blob/henson-error-linkage-good/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java >> import static com.f2prateek.dart.example.UnExistingClass.UNEXISTING; >> is a static import to a non-existing class. It will not reproduce the bug >> of javac. We get only errors related to static import. (You can see that >> there is a minor glitch, errors are duplicated, but that is not our main >> concern). >> >> [INFO] ------------------------------------------------------------- >> >> [ERROR] COMPILATION ERROR : >> >> [INFO] ------------------------------------------------------------- >> >> [ERROR] >> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,41] >> cannot find symbol >> >> symbol: class UnExistingClass >> >> location: package com.f2prateek.dart.example >> >> [ERROR] >> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] >> static import only from classes and interfaces >> >> [ERROR] >> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,41] >> cannot find symbol >> >> symbol: class UnExistingClass >> >> location: package com.f2prateek.dart.example >> >> [ERROR] >> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] >> static import only from classes and interfaces >> >> >> To compile it quickly : >> >> 1. >> >> git clone git at github.com:f2prateek/dart.git >> 2. >> >> cd dart >> 3. >> >> git checkout origin/henson-error-linkage-good >> 4. >> >> mvn clean install >> >> >> Library overview >> >> Sample: https://github.com/f2prateek/dart/blob/master/dart-sample >> >> This project is the sample of our annotation processor based library for >> Android. >> >> Just to give you a little background, the lib has 2 parts : Dart & Henson. >> >> >> When creating an activity (~ a screen / JWindow) on Android, you can be >> passed a set of arguments via a Bundle. A bundle is a serialized container >> that contains serialized arguments. >> >> A bundle is like a map, parameters have a name (called key) and a value. >> >> The library is all about navigating from a source activity to a target >> activity and passing arguments via the bundle in a more convenient way. >> When using Dart & Henson together, we completely abstract the Bundle usage. >> >> ---- >> >> Dart allows to annotate fields members in a target screen and to assign >> values to these fields based on the content of the Bundle you receive : >> >> //from SampleActivity on GH >> >> >> public class SampleActivity { >> >> @InjectExtra(?key1?) String s1; //required key >> >> @InjectExtra(?key2?) @Nullable int i1; //optional key >> >> @Override >> protected void onCreate(Bundle bundle) { >> >> Dart.inject(this); >> >> // after this call the field s1 is assigned the value >> // of the entry key1 of the bundle >> >> // it is equivalent to : s = getIntent().getStringExtra(?key1?) >> >> // s1 is a required field in the bundle, whereas i1 is optional. >> >> // If an entry key2 is present, i2 will be assigned to it. >> >> } >> >> } >> >> ---- >> >> Henson allows to build the Bundle in the source activity to reach the >> given target activity. Henson creates a small DSL to build the Bundle, with >> a little state machine to emphasize the required and optional natures of >> parameters. >> >> //from MainActivity on GH >> >> >> public class MainActivity extends Activity { >> >> public void launchTargetActivity() { >> >> Intent intent = Henson.with(this) >> >> .gotoSampleActivity() // here is the generated DSL call >> >> .key1("foo") >> >> .key2(4) >> >> .build(); >> >> startActivity(intent); >> >> } >> >> } >> >> ---- >> >> Both Dart & Henson use annotation processing, which is a very common way >> to do things on Android, mostly for speed reasons (reflection is slow like >> hell, it is not JITed unlike on a standard JVM). Dart does not involve >> calling generated called directly, the code will be called via a little >> reflection. Henson is all about calling generated code. In the sample >> above, Henson class is generated and offers the DSL to build the bundle. >> Nice, no ? :) >> >> Thanks a lot guys, and sorry for this far too long but report, >> >> Daniel & Stephane >> >> 2016-02-11 11:03 GMT-08:00 Jonathan Gibbons >> : >> >>> St?phane, >>> >>> Can you reduce the test case down to a simple one(s) that you can post >>> here? >>> >>> -- Jon >>> >>> >>> >>> On 02/11/2016 10:44 AM, St?phane NICOLAS wrote: >>> >>> Hey Jon, >>> >>> we are going to create an example based on our annotation processor. It >>> will come in the form of a github repo, 1 branch that compiles fine, 2 >>> branches to illustrate different compile problems. Everything is mavenized >>> so it should work out of the box for you. We will also tell you what error >>> messages we have on the 2 failing branches, actual and expected behavior, >>> and provide you with our javac version(s). >>> >>> We hope this can help, thank you very much for your answers. >>> >>> St?phane >>> >>> >>> 2016-02-10 13:25 GMT-08:00 Jonathan Gibbons >> >: >>> >>>> >>>> >>>> On 02/10/2016 12:59 PM, St?phane NICOLAS wrote: >>>> >>>> Thanks Jon for your fast answer. It's quite disappointing but it's >>>> better to know it early. >>>> It's sad to see how much effort we have put in our annotation >>>> processor, that it's a good idea but fails because of some general java >>>> ecosystem issue. >>>> >>>> Though, talking of the issue with team mates, it became more clear. Let >>>> me try to rephrase them more accurately than in my first mail. >>>> >>>> It seems to me that the design of javac could be improved to >>>> accommodate these 2 scenarios : >>>> >>>> 1. in case of a parse error (for instance a missing ; a bad brace, >>>> etc.) , javac should stop everything and report the actual problem, without >>>> getting any further into the analysis and not report any linkage problem >>>> (because javac would know that annotation processors ain't gonna run and >>>> that can create false positive about missing linkages. All other parse >>>> errors should be reported.). It seems to me this would be a healthy "fail >>>> early" design. >>>> >>>> >>>> This is the intent. Generally, javac is supposed to fail reasonably >>>> fast in general, and in that case in particular. If you are seeing >>>> otherwise, please provide a test case, including the version of javac you >>>> are using. >>>> >>>> >>>> >>>> >>>> 1. in case of a linkage error (for instance having a non existing >>>> import / calling a non existing method, etc.) then we should run the >>>> annotation processors on the partial AST. This mechanism is already in >>>> place to accomodate code generation. >>>> Then the linkage problems should be resolved and take into account >>>> the generated code, and only the remaining problems should show up. This is >>>> where javac actually fails because it reports all problems, including those >>>> that can be resolved by the code that is actually generated. Javac reports >>>> problem from a previous internal stage, it doesn't match the latest state >>>> it could reach internally where only 1 problem could not be resolved, the >>>> one that was not related to invoking generated code, it reports all >>>> linkages problem exactly like if no code was generated and no annotation >>>> processor had run. >>>> >>>> >>>> That is the intent. >>>> >>>> Really, there is no way for javac to support those 2 scenarios ? I got >>>> the strong feeling that it should but I understand my knowledge of javac >>>> has huge holes. I have been surprised by the complexity of the compiler's >>>> code. >>>> >>>> Thx again for your answer, it's been tremendously appreciated; there >>>> are just a handful people would could have been able to answer my question >>>> I am very happy someone actually did take the time to do it. >>>> >>>> Stephane >>>> >>>> 2016-02-10 11:41 GMT-08:00 Jonathan Gibbons < >>>> jonathan.gibbons at oracle.com>: >>>> >>>>> >>>>> >>>>> On 02/10/2016 09:09 AM, St?phane NICOLAS wrote: >>>>> >>>>> I am facing a problem with Javac : I got a sweet annotation processor >>>>> that generates a DSL and I invoke the generated code from my main code. >>>>> >>>>> Everything works fine except when there is an error in my main code : >>>>> if I got a compile error in the main code, not related to the generated >>>>> code, like a missing comma (parsing problem), or calling an inexisting >>>>> method (linkage problem), then all calls to the annotation processor are >>>>> marked as errors by the compiler. >>>>> >>>>> Ideally I am just looking for a way to get rid of those error >>>>> messages, and keep only the original one that fails to compile. >>>>> >>>>> AFAIK, javac should support this scenario but it doesn't support it in >>>>> a very convenient way and I don't understand exactly why.. >>>>> >>>>> After reafing the javac code, open jdk 7 & 8, I realized that : >>>>> >>>>> Annotation processors are not called if there is any error to compile >>>>> the code. As the annotation processor are not triggered, the calls to >>>>> generated code get mark as an error. >>>>> >>>>> However, I could, by playing with shouldStopPolicy (+if error and if >>>>> no error) trigger the annotation processor and generate the code. But >>>>> still, I would receive in this case the errors related to calling the >>>>> generated code. Like if the generated code was not taken into account, like >>>>> if I was receiving errors from a previous compilation steps. >>>>> >>>>> I understand that javac parses the code, if it fails there, I will >>>>> receive only an error about the actual problem. And this is great. I just >>>>> want this error to show up, not any other, and it works fine. (Though I am >>>>> wondering if this is always true even I clean my build & generated files >>>>> before compiling) >>>>> >>>>> If there is a linkage problem in my original code, like calling an >>>>> non-existent method, javac will relax the error and trigger the annotation >>>>> processors and try to let them generate the code to see if the generated >>>>> code that satisfies the linkage problem. But then, though there is a state >>>>> in which javac will successfully satisfy all linkage related to generated >>>>> code but not the other linkage error, I get all calls to generated code >>>>> marked as errors. This is my problem. It looks like this internal state of >>>>> the compiler is never accessible and errors returned do not match this >>>>> state but more probably a previous internal state in which all linkage >>>>> errors are aggregated and returned. >>>>> >>>>> I think there is a solution to achieve what I want but I couldn't find >>>>> one. And the situation is bad : it may actually cancel the development of >>>>> the annotation processor lib I am developing. Just because the errors are >>>>> flooding the actual problem in the code. >>>>> >>>>> Would you have some time to advise me, and help me to make the lib >>>>> work as expected. >>>>> My goal is just to get only errors that are not related to calling >>>>> generated code if they are not those who fail the compilation. I don't want >>>>> to see my errors polluted by those calls if they are not responsible for >>>>> breaking the compilation. >>>>> >>>>> Stephane >>>>> >>>>> >>>>> Stephane, >>>>> >>>>> In general, there is no convenient solution for you here, because >>>>> there is no way for javac to predict what unresolved symbols may or may not >>>>> be generated by the annotation processor that has yet to be run. And in >>>>> general, it is not desirable to run annotation processors if the input >>>>> source code has significant errors, such as syntax errors. >>>>> >>>>> -- Jon >>>>> >>>> >>>> >>>> >>> >>> >> >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From steff.nicolas at gmail.com Wed Feb 17 20:37:24 2016 From: steff.nicolas at gmail.com (=?UTF-8?Q?St=C3=A9phane_NICOLAS?=) Date: Wed, 17 Feb 2016 12:37:24 -0800 Subject: Invoking code generated by an annotation processor In-Reply-To: References: <56BB9250.20607@oracle.com> <56BBAAD5.7080807@oracle.com> <56BCDAFB.3040107@oracle.com> <56C4C36B.1090506@oracle.com> <56C4CDEF.8020505@oracle.com> Message-ID: 2016-02-17 12:21 GMT-08:00 St?phane NICOLAS : > > > 2016-02-17 11:45 GMT-08:00 Jonathan Gibbons : > >> >> >> On 02/17/2016 11:36 AM, St?phane NICOLAS wrote: >> >> Thx Jon. >> >> I would say there are 2 levels to answer this : >> 1) in case the error seems non recoverable, javac should just not list >> both recoverable and non recoverable errors. Only the non recoverable ones. >> We would be happy with that. >> >> >> We could *maybe* prioritize the messages, but I think it would be wrong >> to only show non-recoverable errors. Just because an error is recoverable >> doesn't mean that an anno processor will generate code to make the error go >> away. >> >> No, it doesn't mean that, but in our case it is what happens and as the >> annotation processor is not given the chance to run and resolve those >> recoverable errors, they should not be listed. >> > To be more clear, it's not about prioritizing the messages, though it could be a workaround, but it's about not showing the recoverable errors when there are non-recoverable errors. As long as the annotation processors don't run, recoverable errors should not show up. Also, we are wondering if you fully take into account the specifics of the static import issue. Non static import don't behave in the same way, they behave fine. > >> >> 2) I am not sure this difference really holds in the case of "B extends A >> and A is generated", what would be marked as non recoverable is actually >> also recoverable. >> >> >> Generally, recoverable errors are those of the form "name not found", in >> the sense that "name" could maybe be found if an anno processor generates >> the code. >> > > So we were wrong in our understanding as we understood that they were > different levels of "names not found" errors. It looks like when the class > is found and a field not found, the error is ranked as non-recoverable. But > really this case is further to ours, we just added an extra thought so that > bug resolution takes into account the scenario, but it's not our main > concern. > >> >> >> -- Jon >> >> >> >> >> S. >> >> 2016-02-17 11:00 GMT-08:00 Jonathan Gibbons >> : >> >>> St?phane, >>> >>> Internally, during the period before anno processing, javac categorizes >>> errors as recoverable or not, where "recoverable" means "could this error >>> conceivably be fixed by running annotation processors, which may generate >>> code." >>> >>> It may be that we have to examine the scenario you describe to decide if >>> the error should be marked as recoverable. >>> >>> -- Jon >>> >>> >>> On 02/17/2016 10:53 AM, St?phane NICOLAS wrote: >>> >>> Hi Jon, >>> >>> Here is a summary about the bug, it should be enough for you to >>> understand what is going wrong. Later, we will provide you with more >>> details on an example you can use to reproduce the bug. >>> >>> Summary >>> >>> The problem is about static imports and invocation of generated code >>> from main code. >>> >>> In our main code, we invoke some code that is generated by an annotation >>> processor. This scenario is fully supported by javac. However, javac >>> reports the calls to generated code as errors, when it should not, in a >>> very specific scenario. >>> >>> In our main code, if we have an erroneous static import to a non >>> existing member in an existing class, then the annotation processors are >>> not triggered and all calls to the generated code will be marked, unduly, >>> as errors. >>> >>> ? For us this is a very inconvenient bug because it floods developers >>> with too many errors and it becomes very hard to pinpoint the only actual >>> error in the code (the wrong static import statement). This error can >>> actually be triggered very easily when refactoring. >>> >>> Please note that if we have an equally erroneous static import to a non >>> existing class, then the bug doesn?t happen and only this static import >>> will be marked as error. >>> >>> Extra thoughts >>> >>> We realized that we are kind of asking implicitly to distinguish static >>> import errors to existing classes and non existing classes. But this may >>> not be the right approach. It would not accommodate the hacky but possible >>> scenario when you define class B extends A in your main code, and >>> generate the class A. In that case, if A defines a public static field Foo, >>> B would inherit it, and though B exists, B.Foo would not exist before >>> annotation processing completes. >>> The best approach for us seems to be to always run annotation processors >>> even though there are some static imports problems and to resolve them >>> after code generation = annotation processing. Static imports shouldn?t >>> fail so fast.. >>> >>> Details >>> >>> We tested with the following version of Javac : >>> >>> - >>> >>> javac 1.7.0_79 >>> - >>> >>> open JDK javac 1.7.0_79 >>> - >>> >>> javac 1.8.0_60 >>> >>> >>> here is our example : sorry, it will be a bit long to read, but it comes >>> with a full explanation. >>> >>> We first give you easy repro steps and then an overview of the library. >>> >>> Javac issue and reproduction steps >>> >>> We have 3 branches to illustrate the problem : >>> >>> 1. Branch : Master >>> https://github.com/f2prateek/dart/blob/master/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java >>> This branch works fine, there is no compilation error. See below to >>> compile it. >>> >>> To compile it quickly : >>> >>> 1. >>> >>> git clone git at github.com:f2prateek/dart.git >>> 2. >>> >>> cd dart >>> 3. >>> >>> mvn clean install >>> >>> >>> >>> 2. Branch : henson-error-linkage >>> >>> >>> https://github.com/f2prateek/dart/blob/henson-error-linkage/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java >>> import static com.f2prateek.dart.example.SampleActivity.UNEXISTING; >>> is a static import to an existing class but a non existing member. It >>> will reproduce the bug of javac, the compiler will return 2 errors. The >>> call to generated code will also be marked as error : >>> >>> [INFO] ------------------------------------------------------------- >>> >>> [ERROR] COMPILATION ERROR : >>> >>> [INFO] ------------------------------------------------------------- >>> >>> [ERROR] >>> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] >>> cannot find symbol >>> >>> symbol: static UNEXISTING >>> >>> location: class >>> >>> [ERROR] >>> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[39,21] >>> cannot find symbol >>> >>> symbol: variable Henson >>> >>> location: class com.f2prateek.dart.example.MainActivity >>> >>> To compile it quickly : >>> >>> 1. >>> >>> git clone git at github.com:f2prateek/dart.git >>> 2. >>> >>> cd dart >>> 3. >>> >>> git checkout origin/henson-error-linkage >>> 4. >>> >>> mvn clean install >>> >>> >>> >>> 3. Branch : henson-error-linkage-good >>> https://github.com/f2prateek/dart/blob/henson-error-linkage-good/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java >>> import static com.f2prateek.dart.example.UnExistingClass.UNEXISTING; >>> is a static import to a non-existing class. It will not reproduce the >>> bug of javac. We get only errors related to static import. (You can see >>> that there is a minor glitch, errors are duplicated, but that is not our >>> main concern). >>> >>> [INFO] ------------------------------------------------------------- >>> >>> [ERROR] COMPILATION ERROR : >>> >>> [INFO] ------------------------------------------------------------- >>> >>> [ERROR] >>> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,41] >>> cannot find symbol >>> >>> symbol: class UnExistingClass >>> >>> location: package com.f2prateek.dart.example >>> >>> [ERROR] >>> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] >>> static import only from classes and interfaces >>> >>> [ERROR] >>> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,41] >>> cannot find symbol >>> >>> symbol: class UnExistingClass >>> >>> location: package com.f2prateek.dart.example >>> >>> [ERROR] >>> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] >>> static import only from classes and interfaces >>> >>> >>> To compile it quickly : >>> >>> 1. >>> >>> git clone git at github.com:f2prateek/dart.git >>> 2. >>> >>> cd dart >>> 3. >>> >>> git checkout origin/henson-error-linkage-good >>> 4. >>> >>> mvn clean install >>> >>> >>> Library overview >>> >>> Sample: https://github.com/f2prateek/dart/blob/master/dart-sample >>> >>> This project is the sample of our annotation processor based library for >>> Android. >>> >>> Just to give you a little background, the lib has 2 parts : Dart & >>> Henson. >>> >>> When creating an activity (~ a screen / JWindow) on Android, you can be >>> passed a set of arguments via a Bundle. A bundle is a serialized container >>> that contains serialized arguments. >>> >>> A bundle is like a map, parameters have a name (called key) and a value. >>> >>> The library is all about navigating from a source activity to a target >>> activity and passing arguments via the bundle in a more convenient way. >>> When using Dart & Henson together, we completely abstract the Bundle usage. >>> >>> ---- >>> >>> Dart allows to annotate fields members in a target screen and to assign >>> values to these fields based on the content of the Bundle you receive : >>> >>> //from SampleActivity on GH >>> >>> >>> public class SampleActivity { >>> >>> @InjectExtra(?key1?) String s1; //required key >>> >>> @InjectExtra(?key2?) @Nullable int i1; //optional key >>> >>> @Override >>> protected void onCreate(Bundle bundle) { >>> >>> Dart.inject(this); >>> >>> // after this call the field s1 is assigned the value >>> // of the entry key1 of the bundle >>> >>> // it is equivalent to : s = getIntent().getStringExtra(?key1?) >>> >>> // s1 is a required field in the bundle, whereas i1 is optional. >>> >>> // If an entry key2 is present, i2 will be assigned to it. >>> >>> } >>> >>> } >>> >>> ---- >>> >>> Henson allows to build the Bundle in the source activity to reach the >>> given target activity. Henson creates a small DSL to build the Bundle, with >>> a little state machine to emphasize the required and optional natures of >>> parameters. >>> >>> //from MainActivity on GH >>> >>> >>> public class MainActivity extends Activity { >>> >>> public void launchTargetActivity() { >>> >>> Intent intent = Henson.with(this) >>> >>> .gotoSampleActivity() // here is the generated DSL call >>> >>> .key1("foo") >>> >>> .key2(4) >>> >>> .build(); >>> >>> startActivity(intent); >>> >>> } >>> >>> } >>> >>> ---- >>> >>> Both Dart & Henson use annotation processing, which is a very common >>> way to do things on Android, mostly for speed reasons (reflection is slow >>> like hell, it is not JITed unlike on a standard JVM). Dart does not involve >>> calling generated called directly, the code will be called via a little >>> reflection. Henson is all about calling generated code. In the sample >>> above, Henson class is generated and offers the DSL to build the bundle. >>> Nice, no ? :) >>> >>> Thanks a lot guys, and sorry for this far too long but report, >>> >>> Daniel & Stephane >>> >>> 2016-02-11 11:03 GMT-08:00 Jonathan Gibbons >> >: >>> >>>> St?phane, >>>> >>>> Can you reduce the test case down to a simple one(s) that you can post >>>> here? >>>> >>>> -- Jon >>>> >>>> >>>> >>>> On 02/11/2016 10:44 AM, St?phane NICOLAS wrote: >>>> >>>> Hey Jon, >>>> >>>> we are going to create an example based on our annotation processor. It >>>> will come in the form of a github repo, 1 branch that compiles fine, 2 >>>> branches to illustrate different compile problems. Everything is mavenized >>>> so it should work out of the box for you. We will also tell you what error >>>> messages we have on the 2 failing branches, actual and expected behavior, >>>> and provide you with our javac version(s). >>>> >>>> We hope this can help, thank you very much for your answers. >>>> >>>> St?phane >>>> >>>> >>>> 2016-02-10 13:25 GMT-08:00 Jonathan Gibbons < >>>> jonathan.gibbons at oracle.com>: >>>> >>>>> >>>>> >>>>> On 02/10/2016 12:59 PM, St?phane NICOLAS wrote: >>>>> >>>>> Thanks Jon for your fast answer. It's quite disappointing but it's >>>>> better to know it early. >>>>> It's sad to see how much effort we have put in our annotation >>>>> processor, that it's a good idea but fails because of some general java >>>>> ecosystem issue. >>>>> >>>>> Though, talking of the issue with team mates, it became more clear. >>>>> Let me try to rephrase them more accurately than in my first mail. >>>>> >>>>> It seems to me that the design of javac could be improved to >>>>> accommodate these 2 scenarios : >>>>> >>>>> 1. in case of a parse error (for instance a missing ; a bad brace, >>>>> etc.) , javac should stop everything and report the actual problem, without >>>>> getting any further into the analysis and not report any linkage problem >>>>> (because javac would know that annotation processors ain't gonna run and >>>>> that can create false positive about missing linkages. All other parse >>>>> errors should be reported.). It seems to me this would be a healthy "fail >>>>> early" design. >>>>> >>>>> >>>>> This is the intent. Generally, javac is supposed to fail reasonably >>>>> fast in general, and in that case in particular. If you are seeing >>>>> otherwise, please provide a test case, including the version of javac you >>>>> are using. >>>>> >>>>> >>>>> >>>>> >>>>> 1. in case of a linkage error (for instance having a non existing >>>>> import / calling a non existing method, etc.) then we should run the >>>>> annotation processors on the partial AST. This mechanism is already in >>>>> place to accomodate code generation. >>>>> Then the linkage problems should be resolved and take into account >>>>> the generated code, and only the remaining problems should show up. This is >>>>> where javac actually fails because it reports all problems, including those >>>>> that can be resolved by the code that is actually generated. Javac reports >>>>> problem from a previous internal stage, it doesn't match the latest state >>>>> it could reach internally where only 1 problem could not be resolved, the >>>>> one that was not related to invoking generated code, it reports all >>>>> linkages problem exactly like if no code was generated and no annotation >>>>> processor had run. >>>>> >>>>> >>>>> That is the intent. >>>>> >>>>> Really, there is no way for javac to support those 2 scenarios ? I got >>>>> the strong feeling that it should but I understand my knowledge of javac >>>>> has huge holes. I have been surprised by the complexity of the compiler's >>>>> code. >>>>> >>>>> Thx again for your answer, it's been tremendously appreciated; there >>>>> are just a handful people would could have been able to answer my question >>>>> I am very happy someone actually did take the time to do it. >>>>> >>>>> Stephane >>>>> >>>>> 2016-02-10 11:41 GMT-08:00 Jonathan Gibbons < >>>>> jonathan.gibbons at oracle.com>: >>>>> >>>>>> >>>>>> >>>>>> On 02/10/2016 09:09 AM, St?phane NICOLAS wrote: >>>>>> >>>>>> I am facing a problem with Javac : I got a sweet annotation processor >>>>>> that generates a DSL and I invoke the generated code from my main code. >>>>>> >>>>>> Everything works fine except when there is an error in my main code : >>>>>> if I got a compile error in the main code, not related to the generated >>>>>> code, like a missing comma (parsing problem), or calling an inexisting >>>>>> method (linkage problem), then all calls to the annotation processor are >>>>>> marked as errors by the compiler. >>>>>> >>>>>> Ideally I am just looking for a way to get rid of those error >>>>>> messages, and keep only the original one that fails to compile. >>>>>> >>>>>> AFAIK, javac should support this scenario but it doesn't support it >>>>>> in a very convenient way and I don't understand exactly why.. >>>>>> >>>>>> After reafing the javac code, open jdk 7 & 8, I realized that : >>>>>> >>>>>> Annotation processors are not called if there is any error to compile >>>>>> the code. As the annotation processor are not triggered, the calls to >>>>>> generated code get mark as an error. >>>>>> >>>>>> However, I could, by playing with shouldStopPolicy (+if error and if >>>>>> no error) trigger the annotation processor and generate the code. But >>>>>> still, I would receive in this case the errors related to calling the >>>>>> generated code. Like if the generated code was not taken into account, like >>>>>> if I was receiving errors from a previous compilation steps. >>>>>> >>>>>> I understand that javac parses the code, if it fails there, I will >>>>>> receive only an error about the actual problem. And this is great. I just >>>>>> want this error to show up, not any other, and it works fine. (Though I am >>>>>> wondering if this is always true even I clean my build & generated files >>>>>> before compiling) >>>>>> >>>>>> If there is a linkage problem in my original code, like calling an >>>>>> non-existent method, javac will relax the error and trigger the annotation >>>>>> processors and try to let them generate the code to see if the generated >>>>>> code that satisfies the linkage problem. But then, though there is a state >>>>>> in which javac will successfully satisfy all linkage related to generated >>>>>> code but not the other linkage error, I get all calls to generated code >>>>>> marked as errors. This is my problem. It looks like this internal state of >>>>>> the compiler is never accessible and errors returned do not match this >>>>>> state but more probably a previous internal state in which all linkage >>>>>> errors are aggregated and returned. >>>>>> >>>>>> I think there is a solution to achieve what I want but I couldn't >>>>>> find one. And the situation is bad : it may actually cancel the development >>>>>> of the annotation processor lib I am developing. Just because the errors >>>>>> are flooding the actual problem in the code. >>>>>> >>>>>> Would you have some time to advise me, and help me to make the lib >>>>>> work as expected. >>>>>> My goal is just to get only errors that are not related to calling >>>>>> generated code if they are not those who fail the compilation. I don't want >>>>>> to see my errors polluted by those calls if they are not responsible for >>>>>> breaking the compilation. >>>>>> >>>>>> Stephane >>>>>> >>>>>> >>>>>> Stephane, >>>>>> >>>>>> In general, there is no convenient solution for you here, because >>>>>> there is no way for javac to predict what unresolved symbols may or may not >>>>>> be generated by the annotation processor that has yet to be run. And in >>>>>> general, it is not desirable to run annotation processors if the input >>>>>> source code has significant errors, such as syntax errors. >>>>>> >>>>>> -- Jon >>>>>> >>>>> >>>>> >>>>> >>>> >>>> >>> >>> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From sven.reimers at gmail.com Wed Feb 17 21:06:35 2016 From: sven.reimers at gmail.com (Sven Reimers) Date: Wed, 17 Feb 2016 22:06:35 +0100 Subject: Compiler creates broken classfiles although errors are shown in output In-Reply-To: References: <56C1EEFC.8010406@oracle.com> <56C220E5.4080104@oracle.com> Message-ID: Ok so here is an example - copy and paste into a shell script, make javac available and run... See the script / output for details. Hope this helps Sven -------- snip here --------- #!/bin/bash mkdir interface cat <interface/I.java public interface I {} EOF mkdir abstract cat <abstract/AImpl.java public abstract class AImpl implements I {} EOF mkdir impl cat <impl/Impl.java public class Impl extends AImpl {} EOF #Now create an AnnotationProcessor: mkdir processor cat <processor/A.java import javax.annotation.processing.*; import java.util.Set; import javax.lang.model.element.TypeElement; import javax.lang.model.SourceVersion; @SupportedSourceVersion(SourceVersion.RELEASE_8) public class A extends AbstractProcessor { @Override public synchronized void init(ProcessingEnvironment env){ System.out.println("Init");} @Override public boolean process(Set annoations, RoundEnvironment env) { System.out.println("process");return true; } } EOF mkdir processor/META-INF mkdir processor/META-INF/services cat <processor/META-INF/services/javax.annotation.processing.Processor A EOF #Now compile all of them to different directories: mkdir build mkdir build/interface javac -d build/interface interface/I.java mkdir build/abstract javac -cp build/interface -d build/abstract abstract/AImpl.java mkdir build/processor javac -d build/processor processor/A.java cp -r processor/META-INF build/processor #Now try to compile Impl.java mkdir build/impl-v1 echo Variant 1: echo javac -cp build/abstract -d build/impl-v1 impl/Impl.java javac -cp build/abstract -d build/impli-v1 impl/Impl.java echo $? #Fails due to missing interface class... exit code = 1 mkdir build/impl-v2 echo Variant 2 echo javac -cp build/abstract -processorpath build/processor -d build/impl-v2 impl/Impl.java javac -cp build/abstract -processorpath build/processor -d build/impl-v2 impl/Impl.java echo $? ls -la build/impl-v2/Impl.class #Does not fail due to missing interface class although output shows the problem... exit code = 0, class file generated but should not mkdir build/impl-v3 echo Variant 3 echo javac -cp build/abstract:build/interface -processorpath build/processor -d build/impl-v3 impl/Impl.java javac -cp build/abstract:build/interface -processorpath build/processor -d build/impl-v3 impl/Impl.java echo $? ls -la build/impl-v3/Impl.class #Succeeds and good class file -------- snip here --------- --- On Tue, Feb 16, 2016 at 3:08 PM, Sven Reimers wrote: > Hi Jan, > > seems the problem is caused by using an annotation processor.. > > It seems sufficient to have an annotation processor doing nothing to > trigger the behaviour. > > Will try to post an example, if you need one.. > > -Sven > Am 15.02.2016 20:03 schrieb "Jan Lahoda" : > >> Hi Sven, >> >> I tried the example with: >> $ javac -fullversion >> javac full version "1.8.0_40-b25" >> >> And it produced: >> $ javac Client.java >> Client.java:7: error: cannot access I >> new A().m(); >> ^ >> class file for p1.I not found >> 1 error >> >> No classfile was written. >> >> With: >> $ javac -fullversion >> javac full version "1.7.0_45-b35" >> >> $ javac Client.java >> >> produced no errors, and written a (correct as far as I can tell) >> classfile (equivalent to a classfile written when I.class is available). >> >> Do you have a testcase where javac produces an error, but writes an >> (incorrect) classfile? >> >> Thanks, >> Jan >> >> On 15.2.2016 17:02, Sven Reimers wrote: >> >>> There is an example in here >>> >>> >>> http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-2156366.html >>> >>> Area: Tools / javac >>> >>> Synopsis >>> >>> Interfaces need to be present when compiling against their >>> implementations >>> >>> Description >>> >>> When compiling a class against another class implementing an interface >>> which is defined in yet another class file, such class file (where >>> interface is defined) must be available in the class path used >>> by javac during compilation. This is a new requirement as of JDK 8 - a >>> failure to do so will result in a compilation error. >>> >>> Example: >>> >>> Client.java: >>> >>> import p1.A; >>> >>> class Client { >>> >>> void test() { >>> >>> new A.m(); >>> >>> } >>> >>> } >>> >>> p1/A.java: >>> >>> package p1; >>> >>> public class A implements I { >>> >>> public void m() { } >>> >>> } >>> >>> p1/I.java: >>> >>> package p1; >>> >>> public interface I { >>> >>> void m(); >>> >>> } >>> >>> If neither p1/I.java nor p1/I.class are available when compiling >>> Client.java, the following error will be displayed: >>> >>> Client.java: error: cannot access I >>> >>> new A().m(); >>> >>> ^ >>> >>> class file for p1.I not found >>> >>> >>> If this does not reproduce the problem, I will try to reduce our code >>> sample >>> >>> Thanks >>> >>> Sven >>> >>> >>> Hi Sven, >>> >>> Would you have a testcase on which this can be seen? >>> >>> Thanks, >>> Jan >>> >>> On 15.2.2016 15:34, Sven Reimers wrote: >>> >>> > >>> > Hi, >>> > >>> > I just ran intohttps://bugs.openjdk.java.net/browse/JDK-8145208 >>> >>> > >>> > The main problem is not to fix the error, but our continuous >>> > integration is not creating breaking builds, so the error can get >>> > unnoticed into builds and fails at runtime. >>> > >>> > Any idea if this can be fixed in an upcoming jdk 8u release? >>> > >>> > Any idea how to make the build break in this case? >>> > >>> > Thanks for your help >>> > >>> > -Sven >>> > >>> >>> -- Sven Reimers * Senior Expert Software Architect * Java Champion * NetBeans Dream Team Member: http://dreamteam.netbeans.org * Community Leader NetBeans: http://community.java.net/netbeans Desktop Java: http://community.java.net/javadesktop * JUG Leader JUG Bodensee: http://www.jug-bodensee.de * Duke's Choice Award Winner 2009 * Blog: https://www.java.net//blog/sven * XING: https://www.xing.com/profile/Sven_Reimers8 * LinkedIn: http://www.linkedin.com/in/svenreimers Join the NetBeans Groups: * XING: http://www.xing.com/group-20148.82db20 * NUGM: http://haug-server.dyndns.org/display/NUGM/Home * LinkedIn: http://www.linkedin.com/groups?gid=1860468 http://www.linkedin.com/groups?gid=107402 http://www.linkedin.com/groups?gid=1684717 * Oracle: https://mix.oracle.com/groups/18497 -------------- next part -------------- An HTML attachment was scrubbed... URL: From dalibor.topic at oracle.com Wed Feb 17 23:41:37 2016 From: dalibor.topic at oracle.com (dalibor topic) Date: Thu, 18 Feb 2016 00:41:37 +0100 Subject: Question about submitting bugs In-Reply-To: References: <56C4A62D.3080806@oracle.com> Message-ID: <56C50531.7070705@oracle.com> On 17.02.2016 19:11, Liam Miller-Cushon wrote: > Usually I wait a few weeks and look up the review ID using my favourite > search engine. It'd be helpful if there was an automated notification, > or if the bugs could be assigned stable IDs from the beginning. The incident IDs are stable and can be alternatively used to query JBS. https://wiki.openjdk.java.net/display/general/JBS+Overview "Users without an account can also use bugs.sun.com to submit an issue. When such an issue is submitted, a record is created in the Java Incidents (JI) project in JBS; at the time of launch, the JI project is not publicly visible. Issues in the JI project have an identifier like JI-9XXXXXX, where the numeric portion corresponds to the bug identifier sent back to the submitter. After an initial triage process, if the incidents needs further review, it can be transferred to be an issue in the JDK project. When such a transfer occurs, the issue gets a new identifier in the JDK project (JDK-8YYYYYY) but references to the original JI-9XXXXXX number will be redirected." e.g. https://bugs.openjdk.java.net/browse/JI-9XXXXXX will redirect to the corresponding issue in the JDK Project in JBS once it has been triaged. cheers, dalibor topic -- Dalibor Topic | Principal Product Manager Phone: +494089091214 | Mobile: +491737185961 ORACLE Deutschland B.V. & Co. KG | K?hneh?fe 5 | 22761 Hamburg ORACLE Deutschland B.V. & Co. KG Hauptverwaltung: Riesstr. 25, D-80992 M?nchen Registergericht: Amtsgericht M?nchen, HRA 95603 Komplement?rin: ORACLE Deutschland Verwaltung B.V. Hertogswetering 163/167, 3543 AS Utrecht, Niederlande Handelsregister der Handelskammer Midden-Niederlande, Nr. 30143697 Gesch?ftsf?hrer: Alexander van der Ven, Jan Schultheiss, Val Maher Oracle is committed to developing practices and products that help protect the environment From jonathan.gibbons at oracle.com Wed Feb 17 23:55:12 2016 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Wed, 17 Feb 2016 15:55:12 -0800 Subject: Question about submitting bugs In-Reply-To: <56C50531.7070705@oracle.com> References: <56C4A62D.3080806@oracle.com> <56C50531.7070705@oracle.com> Message-ID: <56C50860.4000202@oracle.com> Of course, the reference to bugs.sun.com is a throwback to times past, and should arguably be updated ;-) -- Jon On 02/17/2016 03:41 PM, dalibor topic wrote: > > > On 17.02.2016 19:11, Liam Miller-Cushon wrote: >> Usually I wait a few weeks and look up the review ID using my favourite >> search engine. It'd be helpful if there was an automated notification, >> or if the bugs could be assigned stable IDs from the beginning. > > The incident IDs are stable and can be alternatively used to query JBS. > > https://wiki.openjdk.java.net/display/general/JBS+Overview > > "Users without an account can also use bugs.sun.com to submit an > issue. When such an issue is submitted, a record is created in the > Java Incidents (JI) project in JBS; at the time of launch, the JI > project is not publicly visible. Issues in the JI project have an > identifier like JI-9XXXXXX, where the numeric portion corresponds to > the bug identifier sent back to the submitter. After an initial triage > process, if the incidents needs further review, it can be transferred > to be an issue in the JDK project. When such a transfer occurs, the > issue gets a new identifier in the JDK project (JDK-8YYYYYY) but > references to the original JI-9XXXXXX number will be redirected." > > e.g. https://bugs.openjdk.java.net/browse/JI-9XXXXXX will redirect to > the corresponding issue in the JDK Project in JBS once it has been > triaged. > > cheers, > dalibor topic From dalibor.topic at oracle.com Wed Feb 17 23:59:27 2016 From: dalibor.topic at oracle.com (dalibor topic) Date: Thu, 18 Feb 2016 00:59:27 +0100 Subject: Question about submitting bugs In-Reply-To: References: <56C4A62D.3080806@oracle.com> <56C4B44C.1040602@oracle.com> Message-ID: <56C5095F.5010101@oracle.com> On 17.02.2016 19:25, Archie Cobbs wrote: > > The review ID was JI-9025344, received in October 2015. Nothing else has > been received as of now, though in this case it's only been 4 months (is > that normal or slow?) https://bugs.openjdk.java.net/browse/JI-9025344 redirects to https://bugs.openjdk.java.net/browse/JDK-8145978 . > Review ID JI-9013936 as above -> https://bugs.openjdk.java.net/browse/JDK-8054213 > Bug ID 9009951 > Compiler crash - AssertionError as above -> https://bugs.openjdk.java.net/browse/JDK-8032971 > Bug ID 9001645 > Javadoc omitting static final fields as above -> https://bugs.openjdk.java.net/browse/JDK-8015249 > As you can see, the system makes it pretty hard to get any feedback > about what's going on with the issue, or even to understand what > expectations to have. I think the largest missing link here is the difference between the incident ID, and the actual bug ID in the JDK Project, once the issue has been triaged. You can use bugs.openjdk.java.net to check if your bug report has been triaged and look up the actual bug ID, though, as shown above, once you receive an incident ID. cheers, dalibor topic -- Dalibor Topic | Principal Product Manager Phone: +494089091214 | Mobile: +491737185961 ORACLE Deutschland B.V. & Co. KG | K?hneh?fe 5 | 22761 Hamburg ORACLE Deutschland B.V. & Co. KG Hauptverwaltung: Riesstr. 25, D-80992 M?nchen Registergericht: Amtsgericht M?nchen, HRA 95603 Komplement?rin: ORACLE Deutschland Verwaltung B.V. Hertogswetering 163/167, 3543 AS Utrecht, Niederlande Handelsregister der Handelskammer Midden-Niederlande, Nr. 30143697 Gesch?ftsf?hrer: Alexander van der Ven, Jan Schultheiss, Val Maher Oracle is committed to developing practices and products that help protect the environment From jan.lahoda at oracle.com Thu Feb 18 10:39:35 2016 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Thu, 18 Feb 2016 11:39:35 +0100 Subject: Compiler creates broken classfiles although errors are shown in output In-Reply-To: References: <56C1EEFC.8010406@oracle.com> <56C220E5.4080104@oracle.com> Message-ID: <56C59F67.7090907@oracle.com> Hi Sven, Thanks for the testcase - I can reproduce on JDK 8 now. I've augmented the bug report with the testcase. Does not happen on JDK 9. I'll see what should be done. Thanks, Jan On 17.2.2016 22:06, Sven Reimers wrote: > Ok so here is an example - copy and paste into a shell script, make > javac available and run... > > See the script / output for details. > > Hope this helps > > Sven > > -------- snip here --------- > #!/bin/bash > mkdir interface > cat <interface/I.java > public interface I {} > EOF > > mkdir abstract > cat <abstract/AImpl.java > public abstract class AImpl implements I {} > EOF > > mkdir impl > cat <impl/Impl.java > public class Impl extends AImpl {} > EOF > > #Now create an AnnotationProcessor: > > mkdir processor > > cat <processor/A.java > import javax.annotation.processing.*; > import java.util.Set; > import javax.lang.model.element.TypeElement; > import javax.lang.model.SourceVersion; > > @SupportedSourceVersion(SourceVersion.RELEASE_8) > public class A extends AbstractProcessor { > > @Override > public synchronized void init(ProcessingEnvironment env){ > System.out.println("Init");} > > @Override > public boolean process(Set annoations, > RoundEnvironment env) { System.out.println("process");return true; } > > } > EOF > mkdir processor/META-INF > mkdir processor/META-INF/services > > cat <processor/META-INF/services/javax.annotation.processing.Processor > A > EOF > #Now compile all of them to different directories: > > mkdir build > > mkdir build/interface > javac -d build/interface interface/I.java > > mkdir build/abstract > javac -cp build/interface -d build/abstract abstract/AImpl.java > > mkdir build/processor > javac -d build/processor processor/A.java > cp -r processor/META-INF build/processor > > #Now try to compile Impl.java > > mkdir build/impl-v1 > echo Variant 1: > echo javac -cp build/abstract -d build/impl-v1 impl/Impl.java > javac -cp build/abstract -d build/impli-v1 impl/Impl.java > echo $? > > #Fails due to missing interface class... exit code = 1 > > mkdir build/impl-v2 > echo Variant 2 > echo javac -cp build/abstract -processorpath build/processor -d > build/impl-v2 impl/Impl.java > javac -cp build/abstract -processorpath build/processor -d build/impl-v2 > impl/Impl.java > echo $? > ls -la build/impl-v2/Impl.class > #Does not fail due to missing interface class although output shows the > problem... exit code = 0, class file generated but should not > > mkdir build/impl-v3 > echo Variant 3 > echo javac -cp build/abstract:build/interface -processorpath > build/processor -d build/impl-v3 impl/Impl.java > javac -cp build/abstract:build/interface -processorpath build/processor > -d build/impl-v3 impl/Impl.java > echo $? > ls -la build/impl-v3/Impl.class > > #Succeeds and good class file > -------- snip here --------- > --- > > On Tue, Feb 16, 2016 at 3:08 PM, Sven Reimers > wrote: > > Hi Jan, > > seems the problem is caused by using an annotation processor.. > > It seems sufficient to have an annotation processor doing nothing to > trigger the behaviour. > > Will try to post an example, if you need one.. > > -Sven > > Am 15.02.2016 20:03 schrieb "Jan Lahoda" >: > > Hi Sven, > > I tried the example with: > $ javac -fullversion > javac full version "1.8.0_40-b25" > > And it produced: > $ javac Client.java > Client.java:7: error: cannot access I > new A().m(); > ^ > class file for p1.I not found > 1 error > > No classfile was written. > > With: > $ javac -fullversion > javac full version "1.7.0_45-b35" > > $ javac Client.java > > produced no errors, and written a (correct as far as I can tell) > classfile (equivalent to a classfile written when I.class is > available). > > Do you have a testcase where javac produces an error, but writes > an (incorrect) classfile? > > Thanks, > Jan > > On 15.2.2016 17:02, Sven Reimers wrote: > > There is an example in here > > http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-2156366.html > > Area: Tools / javac > > Synopsis > > Interfaces need to be present when compiling against their > implementations > > Description > > When compiling a class against another class implementing an > interface > which is defined in yet another class file, such class file > (where > interface is defined) must be available in the class path used > by javac during compilation. This is a new requirement as of > JDK 8 - a > failure to do so will result in a compilation error. > > Example: > > Client.java: > > import p1.A; > > class Client { > > void test() { > > new A.m(); > > } > > } > > p1/A.java: > > package p1; > > public class A implements I { > > public void m() { } > > } > > p1/I.java: > > package p1; > > public interface I { > > void m(); > > } > > If neither p1/I.java nor p1/I.class are available when compiling > Client.java, the following error will be displayed: > > Client.java: error: cannot access I > > new A().m(); > > ^ > > class file for p1.I not found > > > If this does not reproduce the problem, I will try to reduce > our code sample > > Thanks > > Sven > > > Hi Sven, > > Would you have a testcase on which this can be seen? > > Thanks, > Jan > > On 15.2.2016 15:34, Sven Reimers wrote: > > > > > Hi, > > > > I just ran > intohttps://bugs.openjdk.java.net/browse/JDK-8145208 > > > > > > The main problem is not to fix the error, but our > continuous > > integration is not creating breaking builds, so the > error can get > > unnoticed into builds and fails at runtime. > > > > Any idea if this can be fixed in an upcoming jdk 8u > release? > > > > Any idea how to make the build break in this case? > > > > Thanks for your help > > > > -Sven > > > > > > > -- > Sven Reimers > > * Senior Expert Software Architect > * Java Champion > * NetBeans Dream Team Member: http://dreamteam.netbeans.org > * Community Leader NetBeans: http://community.java.net/netbeans > Desktop Java: > http://community.java.net/javadesktop > * JUG Leader JUG Bodensee: http://www.jug-bodensee.de > * Duke's Choice Award Winner 2009 > * Blog: https://www.java.net//blog/sven > > * XING: https://www.xing.com/profile/Sven_Reimers8 > * LinkedIn: http://www.linkedin.com/in/svenreimers > > Join the NetBeans Groups: > * XING: http://www.xing.com/group-20148.82db20 > * NUGM: http://haug-server.dyndns.org/display/NUGM/Home > * LinkedIn: http://www.linkedin.com/groups?gid=1860468 > http://www.linkedin.com/groups?gid=107402 > http://www.linkedin.com/groups?gid=1684717 > * Oracle: https://mix.oracle.com/groups/18497 From balchandra.vaidya at oracle.com Thu Feb 18 11:48:26 2016 From: balchandra.vaidya at oracle.com (Balchandra Vaidya) Date: Thu, 18 Feb 2016 17:18:26 +0530 Subject: Question about submitting bugs In-Reply-To: <56C50860.4000202@oracle.com> References: <56C4A62D.3080806@oracle.com> <56C50531.7070705@oracle.com> <56C50860.4000202@oracle.com> Message-ID: <56C5AF8A.4010201@oracle.com> Agreed. Update from bugs.sun.com to bugs.java.com (bugreport.sun.com to bugreport.java.com) in some places happened in 8u72 and 9 through JDK-8133454 and in 9 through JDK-8081359. Some more updates are on the way.. Thanks Balchandra On 2/18/2016 5:25 AM, Jonathan Gibbons wrote: > Of course, the reference to bugs.sun.com is a throwback to times past, > and should arguably be updated ;-) > > -- Jon > > On 02/17/2016 03:41 PM, dalibor topic wrote: >> >> >> On 17.02.2016 19:11, Liam Miller-Cushon wrote: >>> Usually I wait a few weeks and look up the review ID using my favourite >>> search engine. It'd be helpful if there was an automated notification, >>> or if the bugs could be assigned stable IDs from the beginning. >> >> The incident IDs are stable and can be alternatively used to query JBS. >> >> https://wiki.openjdk.java.net/display/general/JBS+Overview >> >> "Users without an account can also use bugs.sun.com to submit an >> issue. When such an issue is submitted, a record is created in the >> Java Incidents (JI) project in JBS; at the time of launch, the JI >> project is not publicly visible. Issues in the JI project have an >> identifier like JI-9XXXXXX, where the numeric portion corresponds to >> the bug identifier sent back to the submitter. After an initial >> triage process, if the incidents needs further review, it can be >> transferred to be an issue in the JDK project. When such a transfer >> occurs, the issue gets a new identifier in the JDK project >> (JDK-8YYYYYY) but references to the original JI-9XXXXXX number will >> be redirected." >> >> e.g. https://bugs.openjdk.java.net/browse/JI-9XXXXXX will redirect to >> the corresponding issue in the JDK Project in JBS once it has been >> triaged. >> >> cheers, >> dalibor topic > From archie at dellroad.org Thu Feb 18 15:33:40 2016 From: archie at dellroad.org (Archie Cobbs) Date: Thu, 18 Feb 2016 09:33:40 -0600 Subject: Question about submitting bugs In-Reply-To: <56C5095F.5010101@oracle.com> References: <56C4A62D.3080806@oracle.com> <56C4B44C.1040602@oracle.com> <56C5095F.5010101@oracle.com> Message-ID: Hi Dalibor, It's good to know that those bugs were not actually dropped... On Wed, Feb 17, 2016 at 5:59 PM, dalibor topic wrote: > As you can see, the system makes it pretty hard to get any feedback >> about what's going on with the issue, or even to understand what >> expectations to have. >> > > I think the largest missing link here is the difference between the > incident ID, and the actual bug ID in the JDK Project, once the issue has > been triaged. > So it looks like things are working, with the exception that there may be some problem with email notifications after an incident has been triaged. In any case, here's an easy improvement: include in the initial email the information about how to search by incident ID. Right now this is "secret" knowledge that I was unaware of, but would have helped a lot. Thanks, -Archie -- Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From balchandra.vaidya at oracle.com Fri Feb 19 13:37:15 2016 From: balchandra.vaidya at oracle.com (Balchandra Vaidya) Date: Fri, 19 Feb 2016 19:07:15 +0530 Subject: Question about submitting bugs In-Reply-To: References: <56C4A62D.3080806@oracle.com> <56C4B44C.1040602@oracle.com> <56C5095F.5010101@oracle.com> Message-ID: <56C71A8B.4060202@oracle.com> Archie, All, We understand that there is a major communication issue. However, we are working on a solution where the submitter of a bug can provide additional information using JI-xxxxxxx or JDK-xxxxxxx reference. And, general users should able to add comments to an existing bug using JDK-xxxxxxx reference. We are hoping to roll out the feature soon. In the mean time we will add 'information about how to search a bug' in the initial acknowledgement email. Hope this helps.. Thanks Balchandra On 2/18/2016 9:03 PM, Archie Cobbs wrote: > Hi Dalibor, > > It's good to know that those bugs were not actually dropped... > > On Wed, Feb 17, 2016 at 5:59 PM, dalibor topic > > wrote: > > As you can see, the system makes it pretty hard to get any > feedback > about what's going on with the issue, or even to understand what > expectations to have. > > > I think the largest missing link here is the difference between > the incident ID, and the actual bug ID in the JDK Project, once > the issue has been triaged. > > > So it looks like things are working, with the exception that there may > be some problem with email notifications after an incident has been > triaged. > > In any case, here's an easy improvement: include in the initial email > the information about how to search by incident ID. Right now this is > "secret" knowledge that I was unaware of, but would have helped a lot. > > Thanks, > -Archie > > -- > Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From archie at dellroad.org Fri Feb 19 14:44:13 2016 From: archie at dellroad.org (Archie Cobbs) Date: Fri, 19 Feb 2016 08:44:13 -0600 Subject: Question about submitting bugs In-Reply-To: <56C71A8B.4060202@oracle.com> References: <56C4A62D.3080806@oracle.com> <56C4B44C.1040602@oracle.com> <56C5095F.5010101@oracle.com> <56C71A8B.4060202@oracle.com> Message-ID: Hi Balchandra, That sounds great. I usually try to fix things myself first, but unfortunately in this instance all I can contribute is complaining :) Thanks for listening. -Archie On Fri, Feb 19, 2016 at 7:37 AM, Balchandra Vaidya < balchandra.vaidya at oracle.com> wrote: > We understand that there is a major communication issue. However, we are > working > on a solution where the submitter of a bug can provide additional > information using > JI-xxxxxxx or JDK-xxxxxxx reference. And, general users should able to > add comments to an existing bug using JDK-xxxxxxx reference. We are hoping > to roll out the feature soon. > > In the mean time we will add 'information about how to search a bug' in > the initial > acknowledgement email. > -- Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From iris.clark at oracle.com Fri Feb 19 17:50:14 2016 From: iris.clark at oracle.com (Iris Clark) Date: Fri, 19 Feb 2016 09:50:14 -0800 (PST) Subject: Question about submitting bugs In-Reply-To: <56C50860.4000202@oracle.com> References: <56C4A62D.3080806@oracle.com> <56C50531.7070705@oracle.com> <56C50860.4000202@oracle.com> Message-ID: <9e52c31a-0d94-442a-bffa-0e6c5972b235@default> > Of course, the reference to bugs.sun.com is a throwback to times past, and should arguably be updated ;-) Updated to "bugreport.java.com". Iris From steff.nicolas at gmail.com Fri Feb 19 21:25:57 2016 From: steff.nicolas at gmail.com (=?UTF-8?Q?St=C3=A9phane_NICOLAS?=) Date: Fri, 19 Feb 2016 13:25:57 -0800 Subject: Invoking code generated by an annotation processor In-Reply-To: References: <56BB9250.20607@oracle.com> <56BBAAD5.7080807@oracle.com> <56BCDAFB.3040107@oracle.com> <56C4C36B.1090506@oracle.com> <56C4CDEF.8020505@oracle.com> Message-ID: Hi Jon, we actually find a pretty interesting update on the bug : the same problem arises when we try to use a symbol that is not defined in as the value of an annotation like in @AnnotationExample(A.B.c) //where A or A.B or A.B.c doesn't exist If we have an error here, and we agree it's not recoverable as it prevents annotation processors to run.., then the problem will also appear, exactly in the same way as static imports : all those non recoverable errors will be reported + the recoverable ones, that could be resolved if the annotation processor would have run. We think that this might be important as javac needs to resolve static imports to resolve symbols used in annotation values. Taking into account this new example : our problem is that all non recoverable that prevent the AST to be built and the annotation processor to run also report errors that are recoverable. Hoping not to spam, S. 2016-02-17 12:37 GMT-08:00 St?phane NICOLAS : > > > 2016-02-17 12:21 GMT-08:00 St?phane NICOLAS : > >> >> >> 2016-02-17 11:45 GMT-08:00 Jonathan Gibbons >> : >> >>> >>> >>> On 02/17/2016 11:36 AM, St?phane NICOLAS wrote: >>> >>> Thx Jon. >>> >>> I would say there are 2 levels to answer this : >>> 1) in case the error seems non recoverable, javac should just not list >>> both recoverable and non recoverable errors. Only the non recoverable ones. >>> We would be happy with that. >>> >>> >>> We could *maybe* prioritize the messages, but I think it would be wrong >>> to only show non-recoverable errors. Just because an error is recoverable >>> doesn't mean that an anno processor will generate code to make the error go >>> away. >>> >>> No, it doesn't mean that, but in our case it is what happens and as the >>> annotation processor is not given the chance to run and resolve those >>> recoverable errors, they should not be listed. >>> >> > To be more clear, it's not about prioritizing the messages, though it > could be a workaround, but it's about not showing the recoverable errors > when there are non-recoverable errors. As long as the annotation processors > don't run, recoverable errors should not show up. > Also, we are wondering if you fully take into account the specifics of the > static import issue. Non static import don't behave in the same way, they > behave fine. > >> >>> >>> 2) I am not sure this difference really holds in the case of "B extends >>> A and A is generated", what would be marked as non recoverable is actually >>> also recoverable. >>> >>> >>> Generally, recoverable errors are those of the form "name not found", in >>> the sense that "name" could maybe be found if an anno processor generates >>> the code. >>> >> >> So we were wrong in our understanding as we understood that they were >> different levels of "names not found" errors. It looks like when the class >> is found and a field not found, the error is ranked as non-recoverable. But >> really this case is further to ours, we just added an extra thought so that >> bug resolution takes into account the scenario, but it's not our main >> concern. >> >>> >>> >>> -- Jon >>> >>> >>> >>> >>> S. >>> >>> 2016-02-17 11:00 GMT-08:00 Jonathan Gibbons >> >: >>> >>>> St?phane, >>>> >>>> Internally, during the period before anno processing, javac categorizes >>>> errors as recoverable or not, where "recoverable" means "could this error >>>> conceivably be fixed by running annotation processors, which may generate >>>> code." >>>> >>>> It may be that we have to examine the scenario you describe to decide >>>> if the error should be marked as recoverable. >>>> >>>> -- Jon >>>> >>>> >>>> On 02/17/2016 10:53 AM, St?phane NICOLAS wrote: >>>> >>>> Hi Jon, >>>> >>>> Here is a summary about the bug, it should be enough for you to >>>> understand what is going wrong. Later, we will provide you with more >>>> details on an example you can use to reproduce the bug. >>>> >>>> Summary >>>> >>>> The problem is about static imports and invocation of generated code >>>> from main code. >>>> >>>> In our main code, we invoke some code that is generated by an >>>> annotation processor. This scenario is fully supported by javac. However, >>>> javac reports the calls to generated code as errors, when it should not, in >>>> a very specific scenario. >>>> >>>> In our main code, if we have an erroneous static import to a non >>>> existing member in an existing class, then the annotation processors are >>>> not triggered and all calls to the generated code will be marked, unduly, >>>> as errors. >>>> >>>> ? For us this is a very inconvenient bug because it floods developers >>>> with too many errors and it becomes very hard to pinpoint the only actual >>>> error in the code (the wrong static import statement). This error can >>>> actually be triggered very easily when refactoring. >>>> >>>> Please note that if we have an equally erroneous static import to a non >>>> existing class, then the bug doesn?t happen and only this static import >>>> will be marked as error. >>>> >>>> Extra thoughts >>>> >>>> We realized that we are kind of asking implicitly to distinguish static >>>> import errors to existing classes and non existing classes. But this may >>>> not be the right approach. It would not accommodate the hacky but possible >>>> scenario when you define class B extends A in your main code, and >>>> generate the class A. In that case, if A defines a public static field Foo, >>>> B would inherit it, and though B exists, B.Foo would not exist before >>>> annotation processing completes. >>>> The best approach for us seems to be to always run annotation >>>> processors even though there are some static imports problems and to >>>> resolve them after code generation = annotation processing. Static imports >>>> shouldn?t fail so fast.. >>>> >>>> Details >>>> >>>> We tested with the following version of Javac : >>>> >>>> - >>>> >>>> javac 1.7.0_79 >>>> - >>>> >>>> open JDK javac 1.7.0_79 >>>> - >>>> >>>> javac 1.8.0_60 >>>> >>>> >>>> here is our example : sorry, it will be a bit long to read, but it >>>> comes with a full explanation. >>>> >>>> We first give you easy repro steps and then an overview of the library. >>>> >>>> Javac issue and reproduction steps >>>> >>>> We have 3 branches to illustrate the problem : >>>> >>>> 1. Branch : Master >>>> https://github.com/f2prateek/dart/blob/master/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java >>>> This branch works fine, there is no compilation error. See below to >>>> compile it. >>>> >>>> To compile it quickly : >>>> >>>> 1. >>>> >>>> git clone git at github.com:f2prateek/dart.git >>>> 2. >>>> >>>> cd dart >>>> 3. >>>> >>>> mvn clean install >>>> >>>> >>>> >>>> 2. Branch : henson-error-linkage >>>> >>>> >>>> https://github.com/f2prateek/dart/blob/henson-error-linkage/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java >>>> import static com.f2prateek.dart.example.SampleActivity.UNEXISTING; >>>> is a static import to an existing class but a non existing member. It >>>> will reproduce the bug of javac, the compiler will return 2 errors. The >>>> call to generated code will also be marked as error : >>>> >>>> [INFO] ------------------------------------------------------------- >>>> >>>> [ERROR] COMPILATION ERROR : >>>> >>>> [INFO] ------------------------------------------------------------- >>>> >>>> [ERROR] >>>> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] >>>> cannot find symbol >>>> >>>> symbol: static UNEXISTING >>>> >>>> location: class >>>> >>>> [ERROR] >>>> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[39,21] >>>> cannot find symbol >>>> >>>> symbol: variable Henson >>>> >>>> location: class com.f2prateek.dart.example.MainActivity >>>> >>>> To compile it quickly : >>>> >>>> 1. >>>> >>>> git clone git at github.com:f2prateek/dart.git >>>> 2. >>>> >>>> cd dart >>>> 3. >>>> >>>> git checkout origin/henson-error-linkage >>>> 4. >>>> >>>> mvn clean install >>>> >>>> >>>> >>>> 3. Branch : henson-error-linkage-good >>>> https://github.com/f2prateek/dart/blob/henson-error-linkage-good/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java >>>> import static com.f2prateek.dart.example.UnExistingClass.UNEXISTING; >>>> is a static import to a non-existing class. It will not reproduce the >>>> bug of javac. We get only errors related to static import. (You can >>>> see that there is a minor glitch, errors are duplicated, but that is not >>>> our main concern). >>>> >>>> [INFO] ------------------------------------------------------------- >>>> >>>> [ERROR] COMPILATION ERROR : >>>> >>>> [INFO] ------------------------------------------------------------- >>>> >>>> [ERROR] >>>> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,41] >>>> cannot find symbol >>>> >>>> symbol: class UnExistingClass >>>> >>>> location: package com.f2prateek.dart.example >>>> >>>> [ERROR] >>>> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] >>>> static import only from classes and interfaces >>>> >>>> [ERROR] >>>> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,41] >>>> cannot find symbol >>>> >>>> symbol: class UnExistingClass >>>> >>>> location: package com.f2prateek.dart.example >>>> >>>> [ERROR] >>>> /Users/dmolinero/Development/dart/dart-sample/src/main/java/com/f2prateek/dart/example/MainActivity.java:[26,1] >>>> static import only from classes and interfaces >>>> >>>> >>>> To compile it quickly : >>>> >>>> 1. >>>> >>>> git clone git at github.com:f2prateek/dart.git >>>> 2. >>>> >>>> cd dart >>>> 3. >>>> >>>> git checkout origin/henson-error-linkage-good >>>> 4. >>>> >>>> mvn clean install >>>> >>>> >>>> Library overview >>>> >>>> Sample: https://github.com/f2prateek/dart/blob/master/dart-sample >>>> >>>> This project is the sample of our annotation processor based library >>>> for Android. >>>> >>>> Just to give you a little background, the lib has 2 parts : Dart & >>>> Henson. >>>> >>>> When creating an activity (~ a screen / JWindow) on Android, you can be >>>> passed a set of arguments via a Bundle. A bundle is a serialized container >>>> that contains serialized arguments. >>>> >>>> A bundle is like a map, parameters have a name (called key) and a value. >>>> >>>> The library is all about navigating from a source activity to a target >>>> activity and passing arguments via the bundle in a more convenient way. >>>> When using Dart & Henson together, we completely abstract the Bundle usage. >>>> >>>> ---- >>>> >>>> Dart allows to annotate fields members in a target screen and to >>>> assign values to these fields based on the content of the Bundle you >>>> receive : >>>> >>>> //from SampleActivity on GH >>>> >>>> >>>> public class SampleActivity { >>>> >>>> @InjectExtra(?key1?) String s1; //required key >>>> >>>> @InjectExtra(?key2?) @Nullable int i1; //optional key >>>> >>>> @Override >>>> protected void onCreate(Bundle bundle) { >>>> >>>> Dart.inject(this); >>>> >>>> // after this call the field s1 is assigned the value >>>> // of the entry key1 of the bundle >>>> >>>> // it is equivalent to : s = getIntent().getStringExtra(?key1?) >>>> >>>> // s1 is a required field in the bundle, whereas i1 is optional. >>>> >>>> // If an entry key2 is present, i2 will be assigned to it. >>>> >>>> } >>>> >>>> } >>>> >>>> ---- >>>> >>>> Henson allows to build the Bundle in the source activity to reach the >>>> given target activity. Henson creates a small DSL to build the Bundle, with >>>> a little state machine to emphasize the required and optional natures of >>>> parameters. >>>> >>>> //from MainActivity on GH >>>> >>>> >>>> public class MainActivity extends Activity { >>>> >>>> public void launchTargetActivity() { >>>> >>>> Intent intent = Henson.with(this) >>>> >>>> .gotoSampleActivity() // here is the generated DSL call >>>> >>>> .key1("foo") >>>> >>>> .key2(4) >>>> >>>> .build(); >>>> >>>> startActivity(intent); >>>> >>>> } >>>> >>>> } >>>> >>>> ---- >>>> >>>> Both Dart & Henson use annotation processing, which is a very common >>>> way to do things on Android, mostly for speed reasons (reflection is slow >>>> like hell, it is not JITed unlike on a standard JVM). Dart does not involve >>>> calling generated called directly, the code will be called via a little >>>> reflection. Henson is all about calling generated code. In the sample >>>> above, Henson class is generated and offers the DSL to build the bundle. >>>> Nice, no ? :) >>>> >>>> Thanks a lot guys, and sorry for this far too long but report, >>>> >>>> Daniel & Stephane >>>> >>>> 2016-02-11 11:03 GMT-08:00 Jonathan Gibbons < >>>> jonathan.gibbons at oracle.com>: >>>> >>>>> St?phane, >>>>> >>>>> Can you reduce the test case down to a simple one(s) that you can post >>>>> here? >>>>> >>>>> -- Jon >>>>> >>>>> >>>>> >>>>> On 02/11/2016 10:44 AM, St?phane NICOLAS wrote: >>>>> >>>>> Hey Jon, >>>>> >>>>> we are going to create an example based on our annotation processor. >>>>> It will come in the form of a github repo, 1 branch that compiles fine, 2 >>>>> branches to illustrate different compile problems. Everything is mavenized >>>>> so it should work out of the box for you. We will also tell you what error >>>>> messages we have on the 2 failing branches, actual and expected behavior, >>>>> and provide you with our javac version(s). >>>>> >>>>> We hope this can help, thank you very much for your answers. >>>>> >>>>> St?phane >>>>> >>>>> >>>>> 2016-02-10 13:25 GMT-08:00 Jonathan Gibbons < >>>>> jonathan.gibbons at oracle.com>: >>>>> >>>>>> >>>>>> >>>>>> On 02/10/2016 12:59 PM, St?phane NICOLAS wrote: >>>>>> >>>>>> Thanks Jon for your fast answer. It's quite disappointing but it's >>>>>> better to know it early. >>>>>> It's sad to see how much effort we have put in our annotation >>>>>> processor, that it's a good idea but fails because of some general java >>>>>> ecosystem issue. >>>>>> >>>>>> Though, talking of the issue with team mates, it became more clear. >>>>>> Let me try to rephrase them more accurately than in my first mail. >>>>>> >>>>>> It seems to me that the design of javac could be improved to >>>>>> accommodate these 2 scenarios : >>>>>> >>>>>> 1. in case of a parse error (for instance a missing ; a bad >>>>>> brace, etc.) , javac should stop everything and report the actual problem, >>>>>> without getting any further into the analysis and not report any linkage >>>>>> problem (because javac would know that annotation processors ain't gonna >>>>>> run and that can create false positive about missing linkages. All other >>>>>> parse errors should be reported.). It seems to me this would be a healthy >>>>>> "fail early" design. >>>>>> >>>>>> >>>>>> This is the intent. Generally, javac is supposed to fail reasonably >>>>>> fast in general, and in that case in particular. If you are seeing >>>>>> otherwise, please provide a test case, including the version of javac you >>>>>> are using. >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> 1. in case of a linkage error (for instance having a non existing >>>>>> import / calling a non existing method, etc.) then we should run the >>>>>> annotation processors on the partial AST. This mechanism is already in >>>>>> place to accomodate code generation. >>>>>> Then the linkage problems should be resolved and take into >>>>>> account the generated code, and only the remaining problems should show up. >>>>>> This is where javac actually fails because it reports all problems, >>>>>> including those that can be resolved by the code that is actually >>>>>> generated. Javac reports problem from a previous internal stage, it doesn't >>>>>> match the latest state it could reach internally where only 1 problem could >>>>>> not be resolved, the one that was not related to invoking generated code, >>>>>> it reports all linkages problem exactly like if no code was generated and >>>>>> no annotation processor had run. >>>>>> >>>>>> >>>>>> That is the intent. >>>>>> >>>>>> Really, there is no way for javac to support those 2 scenarios ? I >>>>>> got the strong feeling that it should but I understand my knowledge of >>>>>> javac has huge holes. I have been surprised by the complexity of the >>>>>> compiler's code. >>>>>> >>>>>> Thx again for your answer, it's been tremendously appreciated; there >>>>>> are just a handful people would could have been able to answer my question >>>>>> I am very happy someone actually did take the time to do it. >>>>>> >>>>>> Stephane >>>>>> >>>>>> 2016-02-10 11:41 GMT-08:00 Jonathan Gibbons < >>>>>> jonathan.gibbons at oracle.com>: >>>>>> >>>>>>> >>>>>>> >>>>>>> On 02/10/2016 09:09 AM, St?phane NICOLAS wrote: >>>>>>> >>>>>>> I am facing a problem with Javac : I got a sweet annotation >>>>>>> processor that generates a DSL and I invoke the generated code from my main >>>>>>> code. >>>>>>> >>>>>>> Everything works fine except when there is an error in my main code >>>>>>> : if I got a compile error in the main code, not related to the generated >>>>>>> code, like a missing comma (parsing problem), or calling an inexisting >>>>>>> method (linkage problem), then all calls to the annotation processor are >>>>>>> marked as errors by the compiler. >>>>>>> >>>>>>> Ideally I am just looking for a way to get rid of those error >>>>>>> messages, and keep only the original one that fails to compile. >>>>>>> >>>>>>> AFAIK, javac should support this scenario but it doesn't support it >>>>>>> in a very convenient way and I don't understand exactly why.. >>>>>>> >>>>>>> After reafing the javac code, open jdk 7 & 8, I realized that : >>>>>>> >>>>>>> Annotation processors are not called if there is any error to >>>>>>> compile the code. As the annotation processor are not triggered, the calls >>>>>>> to generated code get mark as an error. >>>>>>> >>>>>>> However, I could, by playing with shouldStopPolicy (+if error and if >>>>>>> no error) trigger the annotation processor and generate the code. But >>>>>>> still, I would receive in this case the errors related to calling the >>>>>>> generated code. Like if the generated code was not taken into account, like >>>>>>> if I was receiving errors from a previous compilation steps. >>>>>>> >>>>>>> I understand that javac parses the code, if it fails there, I will >>>>>>> receive only an error about the actual problem. And this is great. I just >>>>>>> want this error to show up, not any other, and it works fine. (Though I am >>>>>>> wondering if this is always true even I clean my build & generated files >>>>>>> before compiling) >>>>>>> >>>>>>> If there is a linkage problem in my original code, like calling an >>>>>>> non-existent method, javac will relax the error and trigger the annotation >>>>>>> processors and try to let them generate the code to see if the generated >>>>>>> code that satisfies the linkage problem. But then, though there is a state >>>>>>> in which javac will successfully satisfy all linkage related to generated >>>>>>> code but not the other linkage error, I get all calls to generated code >>>>>>> marked as errors. This is my problem. It looks like this internal state of >>>>>>> the compiler is never accessible and errors returned do not match this >>>>>>> state but more probably a previous internal state in which all linkage >>>>>>> errors are aggregated and returned. >>>>>>> >>>>>>> I think there is a solution to achieve what I want but I couldn't >>>>>>> find one. And the situation is bad : it may actually cancel the development >>>>>>> of the annotation processor lib I am developing. Just because the errors >>>>>>> are flooding the actual problem in the code. >>>>>>> >>>>>>> Would you have some time to advise me, and help me to make the lib >>>>>>> work as expected. >>>>>>> My goal is just to get only errors that are not related to calling >>>>>>> generated code if they are not those who fail the compilation. I don't want >>>>>>> to see my errors polluted by those calls if they are not responsible for >>>>>>> breaking the compilation. >>>>>>> >>>>>>> Stephane >>>>>>> >>>>>>> >>>>>>> Stephane, >>>>>>> >>>>>>> In general, there is no convenient solution for you here, because >>>>>>> there is no way for javac to predict what unresolved symbols may or may not >>>>>>> be generated by the annotation processor that has yet to be run. And in >>>>>>> general, it is not desirable to run annotation processors if the input >>>>>>> source code has significant errors, such as syntax errors. >>>>>>> >>>>>>> -- Jon >>>>>>> >>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>> >>>> >>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From joe.darcy at oracle.com Sat Feb 20 00:15:23 2016 From: joe.darcy at oracle.com (Joseph D. Darcy) Date: Fri, 19 Feb 2016 16:15:23 -0800 Subject: Invoking code generated by an annotation processor In-Reply-To: <56C4C36B.1090506@oracle.com> References: <56BB9250.20607@oracle.com> <56BBAAD5.7080807@oracle.com> <56BCDAFB.3040107@oracle.com> <56C4C36B.1090506@oracle.com> Message-ID: <56C7B01B.3030609@oracle.com> Hello, On 2/17/2016 11:00 AM, Jonathan Gibbons wrote: > St?phane, > > Internally, during the period before anno processing, javac > categorizes errors as recoverable or not, where "recoverable" means > "could this error conceivably be fixed by running annotation > processors, which may generate code." > > It may be that we have to examine the scenario you describe to decide > if the error should be marked as recoverable. > To provide some additional historical context here, the first generation annotation processing of apt in JDK 5 as well as the standardized successor of javax.lang.model and javax.annotation.processing in JDK 6 and later shared a requirement of having to be able to process incomplete programs. In particular, to allow processors to generated missing subclasses and even superclasses of the the initial set of sources. In general, it is impractical to describe exactly how a compiler should model an incorrect program. The JSR 269 expert group took some some pains to craft a specification would balance the need for predictability while also allowing some room for implementation-specific behavior: current version of this specification with some refinements [1] over the years: > 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 As Jon alluded to earlier in this thread, how javac implements this aspect of the spec has evolved over time with the current intention to forge ahead when generating a missing type could allow the whole set of sources to compile successfully. Cheers, -Joe [1] https://bugs.openjdk.java.net/browse/JDK-7003550 -------------- next part -------------- An HTML attachment was scrubbed... URL: From steff.nicolas at gmail.com Sat Feb 20 03:50:28 2016 From: steff.nicolas at gmail.com (=?UTF-8?Q?St=C3=A9phane_NICOLAS?=) Date: Fri, 19 Feb 2016 19:50:28 -0800 Subject: Invoking code generated by an annotation processor In-Reply-To: <56C7B01B.3030609@oracle.com> References: <56BB9250.20607@oracle.com> <56BBAAD5.7080807@oracle.com> <56BCDAFB.3040107@oracle.com> <56C4C36B.1090506@oracle.com> <56C7B01B.3030609@oracle.com> Message-ID: Thx Joe for this historical precision, I appreciate it. I read carefully, and when the specs says : 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. In the 2 cases we highlighted : a static import error or an erroneous annotation value, it's hard to say here if a source with those errors is syntactically valid. *If we consider it syntactically valid : *then those errors are not recoverable, as they prevent the annotation processor from running. So those errors should be reported. And javac does that. But it also reports all cals to generated code as errors, which is our concern. Later, the specs says : 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();" Here, javac seems to fail in our case as the source code is syntactically valid, but erroneous in some other fashion, but our generated code is not assumed to have the form of empty classes, methods etc.. The annotation processor is simply not run and those errors are reported. So, if such errors are not considered syntax errors, javac doesn't follow the specs. *If we consider the program is not syntactically valid : *then we fall in a loophole of fuzzyness of the specs : a model may or may not be provided as a quality of implementation issue. It looks like it's not possible to generate a model that could be passed to annotation processors because of those errors. Then only those should be reported. I tend to think there is something missing on this matter in the specs you mention : an intermediary class of error. Unrecoverable errors : - syntax errors are about the form of the program (missing commas, braces, etc. name it). Those are reported well by javac, and only them are reported. Perfect - model building errors : static imports and annotation values errors. Those are also reported well by javac but they drag along with them error to generated code, the recoverable errors below. Recoverable errors : - unknown classes or members of known classes : those are not considered as error before annotation processing takes place. Which is OK, but they are reported in case of model building errors, which is our concern. So we can say here, to summarize the problem differently that right after parsing a source and considering it valid, javac open a list of errors it finds in the source. It adds all recoverable errors it finds to save them for a next phase of processing after annotation processing. But at that very precise moment, it also adds to the error list the non recoverable model building errors. And if one is found, then all errors are reported, which is not correct. The solution would be to separate model building errors and recoverable errors right after having considered a program syntactically valid. Maybe there is an intermediary phase needed to identify strictly non recoverable model building errors and list them, before building the model and detecting recoverable errors, which javac handles well. S. 2016-02-19 16:15 GMT-08:00 Joseph D. Darcy : > Hello, > > On 2/17/2016 11:00 AM, Jonathan Gibbons wrote: > > St?phane, > > Internally, during the period before anno processing, javac categorizes > errors as recoverable or not, where "recoverable" means "could this error > conceivably be fixed by running annotation processors, which may generate > code." > > It may be that we have to examine the scenario you describe to decide if > the error should be marked as recoverable. > > > To provide some additional historical context here, the first generation > annotation processing of apt in JDK 5 as well as the standardized successor > of javax.lang.model and javax.annotation.processing in JDK 6 and later > shared a requirement of having to be able to process incomplete programs. > In particular, to allow processors to generated missing subclasses and even > superclasses of the the initial set of sources. > > In general, it is impractical to describe exactly how a compiler should > model an incorrect program. The JSR 269 expert group took some some pains > to craft a specification would balance the need for predictability while > also allowing some room for implementation-specific behavior: current > version of this specification with some refinements [1] over the years: > > 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 > > As Jon alluded to earlier in this thread, how javac implements this aspect > of the spec has evolved over time with the current intention to forge ahead > when generating a missing type could allow the whole set of sources to > compile successfully. > > Cheers, > > -Joe > > [1] https://bugs.openjdk.java.net/browse/JDK-7003550 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jan.lahoda at oracle.com Mon Feb 22 16:53:47 2016 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Mon, 22 Feb 2016 17:53:47 +0100 Subject: RFR: 8149772: cleanup handling of -encoding in JavacFileManager In-Reply-To: <56C2574C.8050808@oracle.com> References: <56C2574C.8050808@oracle.com> Message-ID: <56CB3D1B.8030108@oracle.com> Seems OK to me. Jan On 15.2.2016 23:55, Jonathan Gibbons wrote: > Please review this fix for simple cleanup in the way the -encoding > option is handled in javac. > > JBS: https://bugs.openjdk.java.net/browse/JDK-8149772 > Webrev: http://cr.openjdk.java.net/~jjg/8149772/webrev.00 > > -- Jon From jonathan.gibbons at oracle.com Wed Feb 24 02:50:52 2016 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Tue, 23 Feb 2016 18:50:52 -0800 Subject: RFR: 8150475 -sourcepath / crashes javac Message-ID: <56CD1A8C.2040503@oracle.com> Trivial fix to a temporary problem; the code in question is commented as temporary and has already gone away in the jigsaw/jake world. But it's worth fixing until then. JBS: https://bugs.openjdk.java.net/browse/JDK-8150475 Webrev: http://cr.openjdk.java.net/~jjg/8150475/webrev.00/index.html -- Jon From vicente.romero at oracle.com Wed Feb 24 03:04:01 2016 From: vicente.romero at oracle.com (Vicente-Arturo Romero-Zaldivar) Date: Tue, 23 Feb 2016 19:04:01 -0800 Subject: RFR: 8150475 -sourcepath / crashes javac In-Reply-To: <56CD1A8C.2040503@oracle.com> References: <56CD1A8C.2040503@oracle.com> Message-ID: <56CD1DA1.6010103@oracle.com> approved, Thanks, Vicente On 02/23/2016 06:50 PM, Jonathan Gibbons wrote: > Trivial fix to a temporary problem; the code in question is commented > as temporary and has already gone away in the jigsaw/jake world. But > it's worth fixing until then. > > JBS: https://bugs.openjdk.java.net/browse/JDK-8150475 > Webrev: http://cr.openjdk.java.net/~jjg/8150475/webrev.00/index.html > > -- Jon From volker.simonis at gmail.com Thu Feb 25 12:11:32 2016 From: volker.simonis at gmail.com (Volker Simonis) Date: Thu, 25 Feb 2016 13:11:32 +0100 Subject: RFR(XS): 8150632: jdk.jshell.TaskFactory should use jdk.Version to check for java.specification.version Message-ID: Hi, can I please have a review for the following small patch which fixes a problem with the jshell java.specification.version check: http://cr.openjdk.java.net/~simonis/webrevs/2016/8150632/ https://bugs.openjdk.java.net/browse/JDK-8150632 Currently, jdk.jshell.TaskFactory does a hard check against java.specification.version being "9". Until JDK-8149519 [1] will be resolved, this check will fail for any newer Java release (i.e. 9.0.0.1). But even if JDK-8149519 will be resolved, I think the compare should actually check that java.specification.version is greater or equal to "9". This can be easily done with the new jdk.Version API. Thank you and best regards, Volker [1] https://bugs.openjdk.java.net/browse/JDK-8149519