From srikanth.adayapalam at oracle.com Mon Feb 2 08:11:35 2015 From: srikanth.adayapalam at oracle.com (Srikanth) Date: Mon, 02 Feb 2015 13:41:35 +0530 Subject: An amendment to JEP 213: Milling Project Coin Message-ID: <54CF3137.3050204@oracle.com> Hello list, https://bugs.openjdk.java.net/browse/JDK-8042880 tracking "JEP 213: Milling Project Coin" has undergone a revision to include one more small feature namely the support for private methods in interfaces tracked under https://bugs.openjdk.java.net/browse/JDK-8071453 As will be recalled, this feature was briefly in consideration for inclusion in Java SE 8 as part of the effort to add support for Lambda Expressions, but was withdrawn to enable better focus on higher priority tasks for Java SE 8. It is now proposed that support for private interface methods be undertaken thereby enabling non abstract methods of an interface to share code between them. Thanks! Srikanth -------------- next part -------------- An HTML attachment was scrubbed... URL: From sewen at apache.org Mon Feb 2 15:40:57 2015 From: sewen at apache.org (Stephan Ewen) Date: Mon, 2 Feb 2015 16:40:57 +0100 Subject: Introduce a compiler option to store generic type information about a lambda expression using the Signature Attribute In-Reply-To: <54C57DBB.7040504@oracle.com> References: <54AD4F24.2080605@apache.org> <54AD550A.1050806@oracle.com> <54C57DBB.7040504@oracle.com> Message-ID: Thank you for the reply. It is good to separate the proposal to add generic signatures to synthetic methods from the motivation. I understand that the motivation is a bit unorthodox. This is only a workaround for us - we would gladly go for a different solution, if possible. The original problem is the missing runtime type information for instances of generic types. We do depend on that to a good extend for our use case - a large scale data processing engine, which needs type information for serialization (network transfer), off-heap memory operations, etc. Think of it like in a relational database, that needs to know the schema of the tables. In our case, that schema is the types that go in and out of the data transformation functions (map, reduce, join, filter, ...). The schema may actually include generic type variables, we handle that. Reflection is a less than optimal solution for that. It used to work, because before the lambdas, all definitions of functions came with their very own (anonymous) class, on which we could reflect. With lambdas, this is no longer true - this is where the complication started. A simple uniform way to access generic types or signatures of function instances would be the preferred solution, definitely. Until then, we have to work around. We are also not surfacing any of that behavior to any user of the system, but we only use it inside utility classes. There are many examples where frameworks use non standardized utils, or make a certain assumption about a feature implementation and special case for different Java versions, platforms, or vendors (the netty I/O library, several compression libraries). It is not nice to do it that way, but it has successfully enabled certain use-cases and functionality in Java. On Mon, Jan 26, 2015 at 12:35 AM, Brian Goetz wrote: > There doesn't seem to be anything *wrong* with having a signature > attribute on synthetic methods; the fact that we don't have them now is > more an artifact of how erasure is implemented in the compiler than a > deliberate decision to strip these methods of generic type information. As > we've seen in Project Valhalla, we've been bitten multiple times by missing > generic information (which is missing for reasons that are effectively > accidental.) So I have no problem with the general idea of being more > uniform about including generic signature attributes. > > That said, the motivation that's been presented for adding them now is a > pretty awful one. I get why people want reflection to work over lambda > instances, but that's not how reflection works -- reflection reflects over > classes, not instances. The current translation strategy happens to be one > that, were this attribute there, would enable reflection to "accidentally > work" to provide generic information, but this *will* change, at which > point any reflection-based strategy falls apart (at which point people > accuse of breaking their should-have-never-worked-in-the-first-place > code.) > > > On 1/7/2015 10:47 AM, Maurizio Cimadamore wrote: > >> Hi Timo, >> thanks for the patch - if I'm not mistaken, this would be the very first >> case in which a method marked with ACC_SYNTHETIC also gets a signature >> attribute. I will consult with the rest of the team and see if there's >> any objection. >> >> Cheers >> Maurizio >> >> On 07/01/15 15:22, Timo Walther wrote: >> >>> Hi all, >>> >>> the Java Reflection API allows to access the generic signature of >>> methods through the java.lang.reflect.Method#getGenericReturnType() >>> method. However, this is not yet supported for Lambda expressions. >>> >>> Given the following classes: >>> >>> class Tuple2 { >>> F0 field0; >>> F1 field1; >>> >>> public Tuple2(F0 f0, F1 f1) { >>> this.field0 = f0; >>> this.field1 = f1; >>> } >>> } >>> >>> interface Map { >>> OUT map(IN in); >>> } >>> >>> Currently, there is no solution that allows to get further type >>> information about expressions like: >>> >>> Map> map = (str) -> new Tuple2<>(str, 1); >>> System.out.println(getReturnType(map)) // can only print Tuple2 => >>> information about the Tuple2's fields are always lost >>> >>> Especially data-intensive runtimes (like Apache Flink[0] where I am >>> working on) need as much type information as possible to be efficient. >>> Therefore, we searched for a way to also extract type information from >>> lambda expressions. Adding a generic signature to the generated >>> "lambda$XXX" static methods (at least by using a compiler option) >>> would be the perfect solution. It seems that the JVM Specification >>> does not prohibit such an implementation. An implementation of a later >>> extraction is described here[1]. >>> >>> The Eclipse JDT compiler team is introducing a compiler option >>> "-genericsignature" with version 4.5 M4[2]. >>> >>> I have implemented a patch prototype. It can be found at: >>> http://people.apache.org/~twalthr/patches/lambdaSignature.patch >>> >>> The patch postpones the type erasure of the lambda function's >>> parameters after the generic descriptor has been saved in a newly >>> introduced variable in MethodSymbol (if compiler option >>> "-lambdasignature" is set). The contents of the variable is read in >>> ClassWriter and written to method's Signature attribute in the >>> classfile. Tests are also included. >>> >>> No change to the class file format is required. The change is guarded >>> by a compiler option, so without that addition, nothing should behave >>> differently. >>> >>> >>> [0] http://flink.apache.org/ >>> [1] >>> http://stackoverflow.com/questions/21887358/reflection- >>> type-inference-on-java-8-lambdas >>> >>> [2] https://bugs.eclipse.org/bugs/show_bug.cgi?id=449063 >>> >>> >>> Regards, >>> Timo Walther >>> >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From anna.kozlova at jetbrains.com Mon Feb 2 18:16:24 2015 From: anna.kozlova at jetbrains.com (anna.kozlova at jetbrains.com) Date: Mon, 02 Feb 2015 22:16:24 +0400 Subject: overload resolution with inexact method reference In-Reply-To: References: <54AD4F24.2080605@apache.org> <54AD550A.1050806@oracle.com> <54C57DBB.7040504@oracle.com> Message-ID: <3119b91b47b42f9a84f51ad5f95ee791@jetbrains.com> Hi, given the code class Test { { bar(baz(LinkedHashMap::new)); } > M baz(Supplier< M> mapSupplier) { return null; } void bar(TreeMap t) {} void bar(Object o) {} } How javac understands that bar(TreeMap) is not applicable? Does it calculate the type of baz(LinkedHashMap::new) with inference and all that stuff for all overloads? Thanks, Anna From maurizio.cimadamore at oracle.com Mon Feb 2 18:58:12 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 02 Feb 2015 18:58:12 +0000 Subject: overload resolution with inexact method reference In-Reply-To: <3119b91b47b42f9a84f51ad5f95ee791@jetbrains.com> References: <54AD4F24.2080605@apache.org> <54AD550A.1050806@oracle.com> <54C57DBB.7040504@oracle.com> <3119b91b47b42f9a84f51ad5f95ee791@jetbrains.com> Message-ID: <54CFC8C4.5070309@oracle.com> On 02/02/15 18:16, anna.kozlova at jetbrains.com wrote: > Hi, > > given the code > > class Test { > { > bar(baz(LinkedHashMap::new)); > } > > > M baz(Supplier< M> mapSupplier) { > return null; > } > > void bar(TreeMap t) {} > void bar(Object o) {} > } > > How javac understands that bar(TreeMap) is not > applicable? Does it calculate the type of baz(LinkedHashMap::new) with > inference and all that stuff for all overloads? > This is an issue we are aware of - there is currently no justification for current behavior, see following javac and spec issues: [1] - https://bugs.openjdk.java.net/browse/JDK-8069545 [2] - https://bugs.openjdk.java.net/browse/JDK-8069544 It's essentially a leftover from the old, more complex overload resolution strategy. Maurizio > Thanks, > Anna From forax at univ-mlv.fr Mon Feb 2 22:17:47 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 02 Feb 2015 23:17:47 +0100 Subject: An amendment to JEP 213: Milling Project Coin In-Reply-To: <54CF3137.3050204@oracle.com> References: <54CF3137.3050204@oracle.com> Message-ID: <54CFF78B.3040003@univ-mlv.fr> I'm glad to see this included in Java 9. R?mi On 02/02/2015 09:11 AM, Srikanth wrote: > Hello list, > > https://bugs.openjdk.java.net/browse/JDK-8042880 tracking "JEP 213: > Milling Project Coin" has undergone > a revision to include one more small feature namely the support for > private methods in interfaces > tracked under https://bugs.openjdk.java.net/browse/JDK-8071453 > > As will be recalled, this feature was briefly in consideration for > inclusion in Java SE 8 as part of the effort > to add support for Lambda Expressions, but was withdrawn to enable > better focus on higher priority > tasks for Java SE 8. It is now proposed that support for private > interface methods be undertaken thereby > enabling non abstract methods of an interface to share code between them. > > Thanks! > Srikanth -------------- next part -------------- An HTML attachment was scrubbed... URL: From staffan.larsen at oracle.com Tue Feb 3 09:15:24 2015 From: staffan.larsen at oracle.com (Staffan Larsen) Date: Tue, 3 Feb 2015 10:15:24 +0100 Subject: RFR: JDK-8025636 Hide lambda proxy frames in stacktraces Message-ID: Hi, Please review this patch for hiding the lambda proxy frame in stack traces: bug: https://bugs.openjdk.java.net/browse/JDK-8025636 webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.00/ This is a straightforward addition of the LambdaForm$Hidden annotation to the generated methods. What is surprising is that this works even if LambdaForm$Hidden is a package-private class in java.lang.invoke and thus not accessible from most of the generated classes. There is some discussion of and answers to this in the bug, but essentially this works because the annotation class is never resolved and the code in Hotspot that looks for the annotation amounts to nothing more than string comparisons. Hidden stack frames can be shown by running with ?-XX:+UnlockDiagnosticVMOptions -XX:+ShowHiddenFrames?. For an example of what this patch does, consider this code: Runnable r = () -> { throw new RuntimeException(); }; r.run(); Previously, this would output: java.lang.RuntimeException at pkg.Foo.lambda$main$0(Foo.java:5) at pkg.Foo$$Lambda$1/2001112025.run(:1000000) at pkg.Foo.main(Foo.java:15) With the patch it looks like this: java.lang.RuntimeException at pkg.Foo.lambda$main$0(Foo.java:5) at pkg.Foo.main(Foo.java:15) Thanks, /Staffan -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Tue Feb 3 09:37:28 2015 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Tue, 03 Feb 2015 10:37:28 +0100 Subject: RFR: JDK-8025636 Hide lambda proxy frames in stacktraces In-Reply-To: References: Message-ID: <3E4DB041-7B63-421A-BFF3-A61957E51003@univ-mlv.fr> Looks good for me. R?mi Le 3 f?vrier 2015 10:15:24 CET, Staffan Larsen a ?crit : >Hi, > >Please review this patch for hiding the lambda proxy frame in stack >traces: > >bug: https://bugs.openjdk.java.net/browse/JDK-8025636 > >webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.00/ > > >This is a straightforward addition of the LambdaForm$Hidden annotation >to the generated methods. What is surprising is that this works even if >LambdaForm$Hidden is a package-private class in java.lang.invoke and >thus not accessible from most of the generated classes. There is some >discussion of and answers to this in the bug, but essentially this >works because the annotation class is never resolved and the code in >Hotspot that looks for the annotation amounts to nothing more than >string comparisons. > >Hidden stack frames can be shown by running with >?-XX:+UnlockDiagnosticVMOptions -XX:+ShowHiddenFrames?. > >For an example of what this patch does, consider this code: > > Runnable r = () -> { throw new RuntimeException(); }; > r.run(); > >Previously, this would output: > > java.lang.RuntimeException > at pkg.Foo.lambda$main$0(Foo.java:5) > at pkg.Foo$$Lambda$1/2001112025.run(:1000000) > at pkg.Foo.main(Foo.java:15) > >With the patch it looks like this: > > java.lang.RuntimeException > at pkg.Foo.lambda$main$0(Foo.java:5) > at pkg.Foo.main(Foo.java:15) > > >Thanks, >/Staffan -- Envoy? de mon t?l?phone Android avec K-9 Mail. Excusez la bri?vet?. From anna.kozlova at jetbrains.com Tue Feb 3 10:01:21 2015 From: anna.kozlova at jetbrains.com (anna.kozlova at jetbrains.com) Date: Tue, 03 Feb 2015 14:01:21 +0400 Subject: overload resolution with inexact method reference In-Reply-To: <54CFC8C4.5070309@oracle.com> References: <54AD4F24.2080605@apache.org> "\"<54AD550A.1050806@oracle.com>" <54C57DBB.7040504@oracle.com>" <3119b91b47b42f9a84f51ad5f95ee791@jetbrains.com> <54CFC8C4.5070309@oracle.com> Message-ID: Thanks Maurizio! Is it the same problem if I change outer calls to be generic methods like > B bar(B t) {} B bar(B o) {} ? On 02.02.2015 22:58, Maurizio Cimadamore wrote: > On 02/02/15 18:16, anna.kozlova at jetbrains.com wrote: >> Hi, >> >> given the code >> >> class Test { >> { >> bar(baz(LinkedHashMap::new)); >> } >> >> > M baz(Supplier< M> mapSupplier) { >> return null; >> } >> >> void bar(TreeMap t) {} >> void bar(Object o) {} >> } >> >> How javac understands that bar(TreeMap) is not >> applicable? Does it calculate the type of baz(LinkedHashMap::new) with >> inference and all that stuff for all overloads? >> > This is an issue we are aware of - there is currently no > justification for current behavior, see following javac and spec > issues: > > [1] - https://bugs.openjdk.java.net/browse/JDK-8069545 > [2] - https://bugs.openjdk.java.net/browse/JDK-8069544 > > It's essentially a leftover from the old, more complex overload > resolution strategy. > > Maurizio >> Thanks, >> Anna > > > !DSPAM:35,54cfc8cd104222362839998! From joel.franck at oracle.com Tue Feb 3 19:56:40 2015 From: joel.franck at oracle.com (=?utf-8?Q?Joel_Borggr=C3=A9n-Franck?=) Date: Tue, 3 Feb 2015 20:56:40 +0100 Subject: RFR: JDK-8025636 Hide lambda proxy frames in stacktraces In-Reply-To: References: Message-ID: Hi, > On 03 Feb 2015, at 10:15, Staffan Larsen wrote: > > Hi, > > Please review this patch for hiding the lambda proxy frame in stack traces: > > bug: https://bugs.openjdk.java.net/browse/JDK-8025636 > webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.00/ > > This is a straightforward addition of the LambdaForm$Hidden annotation to the generated methods. What is surprising is that this works even if LambdaForm$Hidden is a package-private class in java.lang.invoke and thus not accessible from most of the generated classes. There is some discussion of and answers to this in the bug, but essentially this works because the annotation class is never resolved and the code in Hotspot that looks for the annotation amounts to nothing more than string comparisons. > Parsing of the annotation by core reflection can of course happen but should be fine. AnnotationParser calls into the generics machinery to get a Class instance for the annotation type, this shouldn?t be a problem since Class.forName() doesn?t care about package visibility when handing out Class instances to the best of my understanding. Also the parsing machinery is in the null loader so it will be able to find the type. The Proxy for the annotation also shouldn?t care about the package visibility since there is only one interface being proxied (again to the best of my knowledge). If someone were to access members of the parsed annotation things might start to break, but there are none. Looks good to me, but you should probably get at reviewer that knows the invoke code better. cheers /Joel From jose.cornado at gmail.com Wed Feb 4 18:55:57 2015 From: jose.cornado at gmail.com (=?UTF-8?Q?Jos=C3=A9_Cornado?=) Date: Wed, 4 Feb 2015 11:55:57 -0700 Subject: Classloaders and Reflection Message-ID: Hello, I couldn't find a VM or Runtime specific list. If you could forward this to the appropriate one, I would appreciate it. I have the following doubt: If I load class A with Classloader B creating instance C and again with Classloader D creating instance E, can I use the same reflection objects on C and E without tripping over each other? Or do I need another java process? Thanks a lot!! -- Jos? Cornado -- home: http://www.efekctive.com blog: http://blogging.efekctive.com ---------------------- Everything has been said before, but since nobody listens we have to keep going back and beginning all over again. Andre Gide -------------- next part -------------- An HTML attachment was scrubbed... URL: From anna.kozlova at jetbrains.com Thu Feb 12 19:51:14 2015 From: anna.kozlova at jetbrains.com (Anna Kozlova) Date: Thu, 12 Feb 2015 20:51:14 +0100 Subject: lambda in result expression of explicitly typed lambda Message-ID: <008a01d046fd$42a9d140$c7fd73c0$@jetbrains.com> Hi, Consider the following code: { Supplier x = foo (() -> () -> {}); } static Supplier foo(Supplier delegate) { return null; } At the applicability check phase I expect B2 to contain <() -> {} -> T>, and according to 18.2.1 it reduces to false ("If T is not a functional interface type (?9.8), the constraint reduces to false"). However 8u40 b23 compiles the code just fine, but why? Thank you, Anna From andreas.lundblad at oracle.com Thu Feb 12 21:50:47 2015 From: andreas.lundblad at oracle.com (Andreas Lundblad) Date: Thu, 12 Feb 2015 22:50:47 +0100 Subject: RFR: 8054717: SJavac should track changes in the public apis of classpath classes! In-Reply-To: <20141215224906.GB6858@e6430> References: <20141127012617.GA17122@e6430> <20141204155932.GC28610@e6430> <20141211104528.GA18525@e6430> <20141215224906.GB6858@e6430> Message-ID: <20150212215046.GA6527@e6430> On Mon, Dec 15, 2014 at 11:49:06PM +0100, Andreas Lundblad wrote: > [...] > > Link to web review: > http://cr.openjdk.java.net/~alundblad/8054717 > > Link to bug report: > http://bugs.openjdk.java.net/browse/JDK-8054717 Attach: /home/alundbla/Downloads/langtools_v0.diff JDK-8066725 patch Version 5 up for review. (See links above.) A few remarks: 1. The attached langtools patch (currently under review) needs to be applied as well. 2. Two changes to CompileJavaModules.gmk are required: - The classpath should be used instead of the bootclasspath (and the bootclasspath should be set to an empty direcotry) - $1_JAVAC_FLAGS := -bootclasspath "$$($1_CLASSPATH)" + $1_JAVAC_FLAGS := -bootclasspath "/home/alundbla/bootcp" -classpath "$$($1_CLASSPATH)" - Eriks current workaround should be disabled: - $$(if $$(filter-out $$($1_SRCS), $$?), $(FIND) $$(@D) -name "*.class" $(FIND_DELETE)) +# $$(if $$(filter-out $$($1_SRCS), $$?), $(FIND) $$(@D) -name "*.class" $(FIND_DELETE)) I've tested the following: - make clean / make images - touch 40 random JDK source files + recompile - change public api of Object (add / remove method or variable) + make sure everything is recompiled - touch Object.java and make sure only java.lang is recompiled - do the same with java/util/logging/Formatter.java and make sure it only affects related modules - build-only job on jprt - all langtools, including sjavac, regression tests best regards, Andreas -------------- next part -------------- A non-text attachment was scrubbed... Name: langtools_v0.diff Type: text/x-diff Size: 15494 bytes Desc: not available URL: From maurizio.cimadamore at oracle.com Thu Feb 12 22:12:50 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 12 Feb 2015 22:12:50 +0000 Subject: lambda in result expression of explicitly typed lambda In-Reply-To: <008a01d046fd$42a9d140$c7fd73c0$@jetbrains.com> References: <008a01d046fd$42a9d140$c7fd73c0$@jetbrains.com> Message-ID: <54DD2562.6080001@oracle.com> On 12/02/15 19:51, Anna Kozlova wrote: > Hi, > > Consider the following code: > > { > Supplier x = foo (() -> () -> {}); > } > > static Supplier foo(Supplier delegate) { > return null; > } > > At the applicability check phase I expect B2 to contain <() -> {} -> T>, and according to 18.2.1 it reduces to false ("If T is not a functional interface type (?9.8), the constraint reduces to false"). > However 8u40 b23 compiles the code just fine, but why? I think it's an issue of timing - i.e. 18.2.1 should not be applied to non-proper types; I believe it should only be applied after you inferred T to be Runnable (form the target) and then incorporated the result into the method target (which then becomes Supplier, and 18.2.1 is happy). The reason as to why 18.2.1 is 'deferred' is buried inside 18.5.2 - long story short, the constraint () -> () -> {} --> Supplier cannot be looked into because it depends on an input inference variable, namely T. Since the constraints formula is not evaluated, 18.2.1 doesn't kick in at this stage. Maurizio > > Thank you, > Anna > From tom.schindl at bestsolution.at Fri Feb 13 11:31:17 2015 From: tom.schindl at bestsolution.at (Tom Schindl) Date: Fri, 13 Feb 2015 12:31:17 +0100 Subject: Accessing final instance variables inside constructur before initialized Message-ID: <54DDE085.30409@bestsolution.at> Hi, I came across some code which compiles and works fine (at runtime) with the Eclipse Java Compiler but fails with javac (8u40). I've stripped it down to this (the original code used lambda expression accessing the instance field). > > public abstract class CompilerTest { > > public CompilerTest() { > System.err.println("Constructor Base: " + getTest()); > } > > protected abstract String getTest(); > > static class SubClass extends CompilerTest { > private final String test; > > public SubClass(String test) { > System.err.println(this.test); // javac fails > this.test = test; > System.err.println(this.test); > } > > @Override > protected String getTest() { > return this.test; > } > > } > > public static void main(String[] args) { > new SubClass("Hello World!"); > } > } So javac fails with > CompilerTest.java:14: error: variable test might not have been initialized > System.err.println(this.test); One might argue that most likely the above code is a really not what the user idented to do but I'm still not sure javac is correct in refusing to compile this piece of code. Tom -- Thomas Schindl, CTO BestSolution.at EDV Systemhaus GmbH Eduard-Bodem-Gasse 5-7, A-6020 Innsbruck http://www.bestsolution.at/ Reg. Nr. FN 222302s am Firmenbuchgericht Innsbruck From anna.kozlova at jetbrains.com Fri Feb 13 12:21:54 2015 From: anna.kozlova at jetbrains.com (Anna Kozlova) Date: Fri, 13 Feb 2015 13:21:54 +0100 Subject: lambda in result expression of explicitly typed lambda In-Reply-To: <54DD2562.6080001@oracle.com> References: <008a01d046fd$42a9d140$c7fd73c0$@jetbrains.com> <54DD2562.6080001@oracle.com> Message-ID: <00dd01d04787$a7a3a0a0$f6eae1e0$@jetbrains.com> Maurizio, My understanding of "pertinent to applicability" was always incomplete. "An explicitly typed lambda expression whose body is an expression that is not pertinent to applicability" when pertinent to applicability is defined for argument expression of a method call. Should the return type of selected functional type be checked if it is a proper type (or that it should not be the type parameter of the method)? Did I missed it in the spec or can this be added there please? Thanks, Anna -----Original Message----- From: Maurizio Cimadamore [mailto:maurizio.cimadamore at oracle.com] Sent: Thursday, February 12, 2015 11:13 PM To: Anna Kozlova; compiler-dev at openjdk.java.net Subject: Re: lambda in result expression of explicitly typed lambda On 12/02/15 19:51, Anna Kozlova wrote: > Hi, > > Consider the following code: > > { > Supplier x = foo (() -> () -> {}); > } > > static Supplier foo(Supplier delegate) { > return null; > } > > At the applicability check phase I expect B2 to contain <() -> {} -> T>, and according to 18.2.1 it reduces to false ("If T is not a functional interface type (?9.8), the constraint reduces to false"). > However 8u40 b23 compiles the code just fine, but why? I think it's an issue of timing - i.e. 18.2.1 should not be applied to non-proper types; I believe it should only be applied after you inferred T to be Runnable (form the target) and then incorporated the result into the method target (which then becomes Supplier, and 18.2.1 is happy). The reason as to why 18.2.1 is 'deferred' is buried inside 18.5.2 - long story short, the constraint () -> () -> {} --> Supplier cannot be looked into because it depends on an input inference variable, namely T. Since the constraints formula is not evaluated, 18.2.1 doesn't kick in at this stage. Maurizio > > Thank you, > Anna > !DSPAM:35,54dd256999801336712104! From maurizio.cimadamore at oracle.com Fri Feb 13 13:27:26 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 13 Feb 2015 13:27:26 +0000 Subject: lambda in result expression of explicitly typed lambda In-Reply-To: <00dd01d04787$a7a3a0a0$f6eae1e0$@jetbrains.com> References: <008a01d046fd$42a9d140$c7fd73c0$@jetbrains.com> <54DD2562.6080001@oracle.com> <00dd01d04787$a7a3a0a0$f6eae1e0$@jetbrains.com> Message-ID: <54DDFBBE.3020305@oracle.com> I guess I'm missing the connection with pertinent to applicability here... anyway, in your example, the lambda is not pertinent to applicability (because, recursively, its nested lambda isn't). This means that, when doing overload resolution, the lambda is ignored - but this doesn't matter here as there's only one 'foo' method, so the compiler picks that as the most specific. I think your question is more about 'invocation type-inference' which happens _after_ overload resolution (when a most specific method has already been chosen). In this case, the spec says that an additional bunch of constraints should be _set up_ for all arguments that are not pertinent to applicability (and hence for your lambda too). This doesn't mean that the constraints are immediately evaluated, as the dependency analysis in 18.5.2 makes sure that arguments constraints are evaluated only when all input type variables have been inferred to something. Maurizio On 13/02/15 12:21, Anna Kozlova wrote: > Maurizio, > > My understanding of "pertinent to applicability" was always incomplete. "An explicitly typed lambda expression whose body is an expression that is not pertinent to applicability" when pertinent to applicability is defined for argument expression of a method call. Should the return type of selected functional type be checked if it is a proper type (or that it should not be the type parameter of the method)? Did I missed it in the spec or can this be added there please? > > Thanks, > Anna > > -----Original Message----- > From: Maurizio Cimadamore [mailto:maurizio.cimadamore at oracle.com] > Sent: Thursday, February 12, 2015 11:13 PM > To: Anna Kozlova; compiler-dev at openjdk.java.net > Subject: Re: lambda in result expression of explicitly typed lambda > > > On 12/02/15 19:51, Anna Kozlova wrote: >> Hi, >> >> Consider the following code: >> >> { >> Supplier x = foo (() -> () -> {}); >> } >> >> static Supplier foo(Supplier delegate) { >> return null; >> } >> >> At the applicability check phase I expect B2 to contain <() -> {} -> T>, and according to 18.2.1 it reduces to false ("If T is not a functional interface type (?9.8), the constraint reduces to false"). >> However 8u40 b23 compiles the code just fine, but why? > I think it's an issue of timing - i.e. 18.2.1 should not be applied to non-proper types; I believe it should only be applied after you inferred T to be Runnable (form the target) and then incorporated the result into the method target (which then becomes Supplier, and 18.2.1 is happy). The reason as to why 18.2.1 is 'deferred' is buried inside > 18.5.2 - long story short, the constraint () -> () -> {} --> Supplier cannot be looked into because it depends on an input inference variable, namely T. Since the constraints formula is not evaluated, 18.2.1 doesn't kick in at this stage. > > Maurizio >> Thank you, >> Anna >> > > !DSPAM:35,54dd256999801336712104! > > From anna.kozlova at jetbrains.com Fri Feb 13 13:47:26 2015 From: anna.kozlova at jetbrains.com (Anna Kozlova) Date: Fri, 13 Feb 2015 14:47:26 +0100 Subject: lambda in result expression of explicitly typed lambda In-Reply-To: <54DDFBBE.3020305@oracle.com> References: <008a01d046fd$42a9d140$c7fd73c0$@jetbrains.com> <54DD2562.6080001@oracle.com> <00dd01d04787$a7a3a0a0$f6eae1e0$@jetbrains.com> <54DDFBBE.3020305@oracle.com> Message-ID: <011301d04793$9a855ba0$cf9012e0$@jetbrains.com> At the applicability check phase of 18.5.1: "C includes, for all i (1 ? i ? k) where ei is pertinent to applicability,?ei ? Fi ??." I treat () -> () -> {} as pertinent to applicability, after that everything goes wrong. If I fix pertinent to applicability check to reject nested lambda, then everything is ok here. So how to treat nested lambda as not pertinent to applicability? Thanks! P.S. javac doesn't compile code { Supplier x = foo(() -> () -> null); } static Supplier foo(Supplier> delegate) { return null; } So it's not enough to have return type non proper. -----Original Message----- From: Maurizio Cimadamore [mailto:maurizio.cimadamore at oracle.com] Sent: Friday, February 13, 2015 2:27 PM To: Anna Kozlova; compiler-dev at openjdk.java.net Subject: Re: lambda in result expression of explicitly typed lambda I guess I'm missing the connection with pertinent to applicability here... anyway, in your example, the lambda is not pertinent to applicability (because, recursively, its nested lambda isn't). This means that, when doing overload resolution, the lambda is ignored - but this doesn't matter here as there's only one 'foo' method, so the compiler picks that as the most specific. I think your question is more about 'invocation type-inference' which happens _after_ overload resolution (when a most specific method has already been chosen). In this case, the spec says that an additional bunch of constraints should be _set up_ for all arguments that are not pertinent to applicability (and hence for your lambda too). This doesn't mean that the constraints are immediately evaluated, as the dependency analysis in 18.5.2 makes sure that arguments constraints are evaluated only when all input type variables have been inferred to something. Maurizio On 13/02/15 12:21, Anna Kozlova wrote: > Maurizio, > > My understanding of "pertinent to applicability" was always incomplete. "An explicitly typed lambda expression whose body is an expression that is not pertinent to applicability" when pertinent to applicability is defined for argument expression of a method call. Should the return type of selected functional type be checked if it is a proper type (or that it should not be the type parameter of the method)? Did I missed it in the spec or can this be added there please? > > Thanks, > Anna > > -----Original Message----- > From: Maurizio Cimadamore [mailto:maurizio.cimadamore at oracle.com] > Sent: Thursday, February 12, 2015 11:13 PM > To: Anna Kozlova; compiler-dev at openjdk.java.net > Subject: Re: lambda in result expression of explicitly typed lambda > > > On 12/02/15 19:51, Anna Kozlova wrote: >> Hi, >> >> Consider the following code: >> >> { >> Supplier x = foo (() -> () -> {}); >> } >> >> static Supplier foo(Supplier delegate) { >> return null; >> } >> >> At the applicability check phase I expect B2 to contain <() -> {} -> T>, and according to 18.2.1 it reduces to false ("If T is not a functional interface type (?9.8), the constraint reduces to false"). >> However 8u40 b23 compiles the code just fine, but why? > I think it's an issue of timing - i.e. 18.2.1 should not be applied to > non-proper types; I believe it should only be applied after you > inferred T to be Runnable (form the target) and then incorporated the > result into the method target (which then becomes Supplier, > and 18.2.1 is happy). The reason as to why 18.2.1 is 'deferred' is > buried inside > 18.5.2 - long story short, the constraint () -> () -> {} --> Supplier cannot be looked into because it depends on an input inference variable, namely T. Since the constraints formula is not evaluated, 18.2.1 doesn't kick in at this stage. > > Maurizio >> Thank you, >> Anna >> > > > > !DSPAM:35,54ddfbcc63031804284693! From maurizio.cimadamore at oracle.com Fri Feb 13 14:29:51 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 13 Feb 2015 14:29:51 +0000 Subject: lambda in result expression of explicitly typed lambda In-Reply-To: <011301d04793$9a855ba0$cf9012e0$@jetbrains.com> References: <008a01d046fd$42a9d140$c7fd73c0$@jetbrains.com> <54DD2562.6080001@oracle.com> <00dd01d04787$a7a3a0a0$f6eae1e0$@jetbrains.com> <54DDFBBE.3020305@oracle.com> <011301d04793$9a855ba0$cf9012e0$@jetbrains.com> Message-ID: <54DE0A5F.30301@oracle.com> See 15.12.2.2 (I made relevant text in bold): "An argument expression is considered pertinent to applicability for a potentially applicable method m unless it has one of the following forms: An implicitly typed lambda expression (?15.27.1). An inexact method reference expression (?15.13.1). *If m is a generic method and the method invocation does not provide explicit type arguments, an explicitly typed lambda expression or an exact method reference expression for which the corresponding target type (as derived from the signature of m) is a type parameter of m.* *An explicitly typed lambda expression whose body is an expression that is not pertinent to applicability*. An explicitly typed lambda expression whose body is a block, where at least one result expression is not pertinent to applicability. A parenthesized expression (?15.8.5) whose contained expression is not pertinent to applicability. A conditional expression (?15.25) whose second or third operand is not pertinent to applicability." Now, the first statement in bold says that a lambda whose target is a type-parameter of 'm' (foo) is not pertinent to applicability. (1) The second statement in bold says that if that the body of an explicit expression lambda is not pertinent to applicability, then the lambda is also not pertinent to applicability. (2) So, question: "is () -> () -> null pertinent to applicability in foo?" To answer that we need to look at the body of the lambda - so, new question: "is () -> null pertinent to applicability in foo?" To answer this, we must first determine the target-type of the lambda, as per (1). We can safely assume that the target of the full lambda (above) is Supplier, which means that the target-type of this lambda is T. So (1) applies - () -> null has a target T where T is a type-variable of the generic method 'foo' (whose applicability is being determined). This means that () -> null is _not_ pertinent to applicability. Which means () -> () -> null is also _not_ pertinent to applicability. I don't see anything missing from the spec - if I really had to pick one thing that is not so crystal-clear, I believe this section is a bit vague as to what happens when the target of a lambda is the type-variable of an outer method call. Maurizio On 13/02/15 13:47, Anna Kozlova wrote: > At the applicability check phase of 18.5.1: "C includes, for all i (1 ? i ? k) where ei is pertinent to applicability,?ei ? Fi ??." > > I treat () -> () -> {} as pertinent to applicability, after that everything goes wrong. If I fix pertinent to applicability check to reject nested lambda, then everything is ok here. > > So how to treat nested lambda as not pertinent to applicability? > > Thanks! > > P.S. > javac doesn't compile code > { > Supplier x = foo(() -> () -> null); > } > > static Supplier foo(Supplier> delegate) { > return null; > } > So it's not enough to have return type non proper. > > -----Original Message----- > From: Maurizio Cimadamore [mailto:maurizio.cimadamore at oracle.com] > Sent: Friday, February 13, 2015 2:27 PM > To: Anna Kozlova; compiler-dev at openjdk.java.net > Subject: Re: lambda in result expression of explicitly typed lambda > > I guess I'm missing the connection with pertinent to applicability here... anyway, in your example, the lambda is not pertinent to applicability (because, recursively, its nested lambda isn't). This means that, when doing overload resolution, the lambda is ignored - but this doesn't matter here as there's only one 'foo' method, so the compiler picks that as the most specific. > > I think your question is more about 'invocation type-inference' which happens _after_ overload resolution (when a most specific method has already been chosen). In this case, the spec says that an additional bunch of constraints should be _set up_ for all arguments that are not pertinent to applicability (and hence for your lambda too). This doesn't mean that the constraints are immediately evaluated, as the dependency analysis in 18.5.2 makes sure that arguments constraints are evaluated only when all input type variables have been inferred to something. > > Maurizio > > On 13/02/15 12:21, Anna Kozlova wrote: >> Maurizio, >> >> My understanding of "pertinent to applicability" was always incomplete. "An explicitly typed lambda expression whose body is an expression that is not pertinent to applicability" when pertinent to applicability is defined for argument expression of a method call. Should the return type of selected functional type be checked if it is a proper type (or that it should not be the type parameter of the method)? Did I missed it in the spec or can this be added there please? >> >> Thanks, >> Anna >> >> -----Original Message----- >> From: Maurizio Cimadamore [mailto:maurizio.cimadamore at oracle.com] >> Sent: Thursday, February 12, 2015 11:13 PM >> To: Anna Kozlova; compiler-dev at openjdk.java.net >> Subject: Re: lambda in result expression of explicitly typed lambda >> >> >> On 12/02/15 19:51, Anna Kozlova wrote: >>> Hi, >>> >>> Consider the following code: >>> >>> { >>> Supplier x = foo (() -> () -> {}); >>> } >>> >>> static Supplier foo(Supplier delegate) { >>> return null; >>> } >>> >>> At the applicability check phase I expect B2 to contain <() -> {} -> T>, and according to 18.2.1 it reduces to false ("If T is not a functional interface type (?9.8), the constraint reduces to false"). >>> However 8u40 b23 compiles the code just fine, but why? >> I think it's an issue of timing - i.e. 18.2.1 should not be applied to >> non-proper types; I believe it should only be applied after you >> inferred T to be Runnable (form the target) and then incorporated the >> result into the method target (which then becomes Supplier, >> and 18.2.1 is happy). The reason as to why 18.2.1 is 'deferred' is >> buried inside >> 18.5.2 - long story short, the constraint () -> () -> {} --> Supplier cannot be looked into because it depends on an input inference variable, namely T. Since the constraints formula is not evaluated, 18.2.1 doesn't kick in at this stage. >> >> Maurizio >>> Thank you, >>> Anna >>> >> >> >> > > !DSPAM:35,54ddfbcc63031804284693! > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex.buckley at oracle.com Fri Feb 13 17:51:21 2015 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 13 Feb 2015 09:51:21 -0800 Subject: Accessing final instance variables inside constructur before initialized In-Reply-To: <54DDE085.30409@bestsolution.at> References: <54DDE085.30409@bestsolution.at> Message-ID: <54DE3999.6020001@oracle.com> javac is correctly implementing the JLS 16.9 specification: "If C [here, SubClass] has no instance initializers or instance variable initializers, then V [here, test] is not definitely assigned (and moreover is definitely unassigned) after an explicit or implicit superclass constructor invocation." Alex On 2/13/2015 3:31 AM, Tom Schindl wrote: > Hi, > > I came across some code which compiles and works fine (at runtime) with > the Eclipse Java Compiler but fails with javac (8u40). > > I've stripped it down to this (the original code used lambda expression > accessing the instance field). > >> >> public abstract class CompilerTest { >> >> public CompilerTest() { >> System.err.println("Constructor Base: " + getTest()); >> } >> >> protected abstract String getTest(); >> >> static class SubClass extends CompilerTest { >> private final String test; >> >> public SubClass(String test) { >> System.err.println(this.test); // javac fails >> this.test = test; >> System.err.println(this.test); >> } >> >> @Override >> protected String getTest() { >> return this.test; >> } >> >> } >> >> public static void main(String[] args) { >> new SubClass("Hello World!"); >> } >> } > > So javac fails with > >> CompilerTest.java:14: error: variable test might not have been initialized >> System.err.println(this.test); > > One might argue that most likely the above code is a really not what the > user idented to do but I'm still not sure javac is correct in refusing > to compile this piece of code. > > Tom > From staffan.larsen at oracle.com Mon Feb 16 07:47:45 2015 From: staffan.larsen at oracle.com (Staffan Larsen) Date: Mon, 16 Feb 2015 08:47:45 +0100 Subject: RFR: JDK-8025636 Hide lambda proxy frames in stacktraces In-Reply-To: References: Message-ID: Brian pointed out to me that this change missed to add the annotation to bridge methods. Here is an updated version that takes those into account. I also needed to update the test to verify that bridge methods were correctly annotated - it got a little bit more complex since I had to force bridges being used. new webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.01/ Thanks, /Staffan > On 3 feb 2015, at 10:15, Staffan Larsen wrote: > > Hi, > > Please review this patch for hiding the lambda proxy frame in stack traces: > > bug: https://bugs.openjdk.java.net/browse/JDK-8025636 > webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.00/ > > This is a straightforward addition of the LambdaForm$Hidden annotation to the generated methods. What is surprising is that this works even if LambdaForm$Hidden is a package-private class in java.lang.invoke and thus not accessible from most of the generated classes. There is some discussion of and answers to this in the bug, but essentially this works because the annotation class is never resolved and the code in Hotspot that looks for the annotation amounts to nothing more than string comparisons. > > Hidden stack frames can be shown by running with ?-XX:+UnlockDiagnosticVMOptions -XX:+ShowHiddenFrames?. > > For an example of what this patch does, consider this code: > > Runnable r = () -> { throw new RuntimeException(); }; > r.run(); > > Previously, this would output: > > java.lang.RuntimeException > at pkg.Foo.lambda$main$0(Foo.java:5) > at pkg.Foo$$Lambda$1/2001112025.run(:1000000) > at pkg.Foo.main(Foo.java:15) > > With the patch it looks like this: > > java.lang.RuntimeException > at pkg.Foo.lambda$main$0(Foo.java:5) > at pkg.Foo.main(Foo.java:15) > > > Thanks, > /Staffan > -------------- next part -------------- An HTML attachment was scrubbed... URL: From vladimir.x.ivanov at oracle.com Mon Feb 16 11:25:47 2015 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Mon, 16 Feb 2015 14:25:47 +0300 Subject: RFR: JDK-8025636 Hide lambda proxy frames in stacktraces In-Reply-To: References: Message-ID: <54E1D3BB.7010408@oracle.com> Looks good. Best regards, Vladimir Ivanov On 2/16/15 10:47 AM, Staffan Larsen wrote: > Brian pointed out to me that this change missed to add the annotation to bridge methods. Here is an updated version that takes those into account. I also needed to update the test to verify that bridge methods were correctly annotated - it got a little bit more complex since I had to force bridges being used. > > new webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.01/ > > Thanks, > /Staffan > > >> On 3 feb 2015, at 10:15, Staffan Larsen wrote: >> >> Hi, >> >> Please review this patch for hiding the lambda proxy frame in stack traces: >> >> bug: https://bugs.openjdk.java.net/browse/JDK-8025636 >> webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.00/ >> >> This is a straightforward addition of the LambdaForm$Hidden annotation to the generated methods. What is surprising is that this works even if LambdaForm$Hidden is a package-private class in java.lang.invoke and thus not accessible from most of the generated classes. There is some discussion of and answers to this in the bug, but essentially this works because the annotation class is never resolved and the code in Hotspot that looks for the annotation amounts to nothing more than string comparisons. >> >> Hidden stack frames can be shown by running with ?-XX:+UnlockDiagnosticVMOptions -XX:+ShowHiddenFrames?. >> >> For an example of what this patch does, consider this code: >> >> Runnable r = () -> { throw new RuntimeException(); }; >> r.run(); >> >> Previously, this would output: >> >> java.lang.RuntimeException >> at pkg.Foo.lambda$main$0(Foo.java:5) >> at pkg.Foo$$Lambda$1/2001112025.run(:1000000) >> at pkg.Foo.main(Foo.java:15) >> >> With the patch it looks like this: >> >> java.lang.RuntimeException >> at pkg.Foo.lambda$main$0(Foo.java:5) >> at pkg.Foo.main(Foo.java:15) >> >> >> Thanks, >> /Staffan >> > From forax at univ-mlv.fr Mon Feb 16 11:40:10 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 16 Feb 2015 12:40:10 +0100 Subject: RFR: JDK-8025636 Hide lambda proxy frames in stacktraces In-Reply-To: References: Message-ID: <54E1D71A.1080906@univ-mlv.fr> Hi Staffan, ASM MethodVisitor API requires to call visitAnnotation before calling visitCode so I think you shoud call visitAnnotation before calling new ForwardingMethodGenerator(mv).generate(). cheers, R?mi On 02/16/2015 08:47 AM, Staffan Larsen wrote: > Brian pointed out to me that this change missed to add the annotation > to bridge methods. Here is an updated version that takes those into > account. I also needed to update the test to verify that bridge > methods were correctly annotated - it got a little bit more complex > since I had to force bridges being used. > > new webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.01/ > > > Thanks, > /Staffan > > >> On 3 feb 2015, at 10:15, Staffan Larsen > > wrote: >> >> Hi, >> >> Please review this patch for hiding the lambda proxy frame in stack >> traces: >> >> bug: https://bugs.openjdk.java.net/browse/JDK-8025636 >> webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.00/ >> >> >> This is a straightforward addition of the LambdaForm$Hidden >> annotation to the generated methods. What is surprising is that this >> works even if LambdaForm$Hidden is a package-private class in >> java.lang.invoke and thus not accessible from most of the generated >> classes. There is some discussion of and answers to this in the bug, >> but essentially this works because the annotation class is never >> resolved and the code in Hotspot that looks for the annotation >> amounts to nothing more than string comparisons. >> >> Hidden stack frames can be shown by running with >> ?-XX:+UnlockDiagnosticVMOptions -XX:+ShowHiddenFrames?. >> >> For an example of what this patch does, consider this code: >> >> Runnable r = () -> { throw new RuntimeException(); }; >> r.run(); >> >> Previously, this would output: >> >> java.lang.RuntimeException >> at pkg.Foo.lambda$main$0(Foo.java:5) >> at pkg.Foo$$Lambda$1/2001112025.run(:1000000) >> at pkg.Foo.main(Foo.java:15) >> >> With the patch it looks like this: >> >> java.lang.RuntimeException >> at pkg.Foo.lambda$main$0(Foo.java:5) >> at pkg.Foo.main(Foo.java:15) >> >> >> Thanks, >> /Staffan >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From staffan.larsen at oracle.com Mon Feb 16 14:25:13 2015 From: staffan.larsen at oracle.com (Staffan Larsen) Date: Mon, 16 Feb 2015 15:25:13 +0100 Subject: RFR: JDK-8025636 Hide lambda proxy frames in stacktraces In-Reply-To: <54E1D71A.1080906@univ-mlv.fr> References: <54E1D71A.1080906@univ-mlv.fr> Message-ID: <7AE8811E-F669-480E-AD91-8300561BD8B7@oracle.com> Good point! new webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.02/ Thanks, /Staffan > On 16 feb 2015, at 12:40, Remi Forax wrote: > > Hi Staffan, > ASM MethodVisitor API requires to call visitAnnotation before calling visitCode so > I think you shoud call visitAnnotation before calling new ForwardingMethodGenerator(mv).generate(). > > cheers, > R?mi > > On 02/16/2015 08:47 AM, Staffan Larsen wrote: >> Brian pointed out to me that this change missed to add the annotation to bridge methods. Here is an updated version that takes those into account. I also needed to update the test to verify that bridge methods were correctly annotated - it got a little bit more complex since I had to force bridges being used. >> >> new webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.01/ >> >> Thanks, >> /Staffan >> >> >>> On 3 feb 2015, at 10:15, Staffan Larsen > wrote: >>> >>> Hi, >>> >>> Please review this patch for hiding the lambda proxy frame in stack traces: >>> >>> bug: https://bugs.openjdk.java.net/browse/JDK-8025636 >>> webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.00/ >>> >>> This is a straightforward addition of the LambdaForm$Hidden annotation to the generated methods. What is surprising is that this works even if LambdaForm$Hidden is a package-private class in java.lang.invoke and thus not accessible from most of the generated classes. There is some discussion of and answers to this in the bug, but essentially this works because the annotation class is never resolved and the code in Hotspot that looks for the annotation amounts to nothing more than string comparisons. >>> >>> Hidden stack frames can be shown by running with ?-XX:+UnlockDiagnosticVMOptions -XX:+ShowHiddenFrames?. >>> >>> For an example of what this patch does, consider this code: >>> >>> Runnable r = () -> { throw new RuntimeException(); }; >>> r.run(); >>> >>> Previously, this would output: >>> >>> java.lang.RuntimeException >>> at pkg.Foo.lambda$main$0(Foo.java:5) >>> at pkg.Foo$$Lambda$1/2001112025.run(:1000000) >>> at pkg.Foo.main(Foo.java:15) >>> >>> With the patch it looks like this: >>> >>> java.lang.RuntimeException >>> at pkg.Foo.lambda$main$0(Foo.java:5) >>> at pkg.Foo.main(Foo.java:15) >>> >>> >>> Thanks, >>> /Staffan >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From anna.kozlova at jetbrains.com Mon Feb 16 17:45:56 2015 From: anna.kozlova at jetbrains.com (Anna Kozlova) Date: Mon, 16 Feb 2015 18:45:56 +0100 Subject: javac 8/9 inconsistency Message-ID: <00af01d04a10$6ad26590$407730b0$@jetbrains.com> Hi, The following code compiles with java 9 (b. 49) but doesn't with 8 (1.8u40 b.23) class Test { public static void foo(Test test) { Test e = create(Test::factory, test); } private static T create(Supplier callback, T defaultVal) { return null; } static

Test

factory() { return null; } } What is correct? BTW I've found https://bugs.openjdk.java.net/browse/JDK-8055963 which explains to me the situation with Test e = create(() -> factory(), test); but the fix version is 9. Would it be backported to java 8? Thank you, Anna -------------- next part -------------- An HTML attachment was scrubbed... URL: From joel.franck at oracle.com Mon Feb 16 17:50:25 2015 From: joel.franck at oracle.com (=?utf-8?Q?Joel_Borggr=C3=A9n-Franck?=) Date: Mon, 16 Feb 2015 18:50:25 +0100 Subject: RFR: JDK-8025636 Hide lambda proxy frames in stacktraces In-Reply-To: <7AE8811E-F669-480E-AD91-8300561BD8B7@oracle.com> References: <54E1D71A.1080906@univ-mlv.fr> <7AE8811E-F669-480E-AD91-8300561BD8B7@oracle.com> Message-ID: <51071589-360E-4ECA-959C-FDF95AE70AB0@oracle.com> +1 cheers /Joel > On 16 Feb 2015, at 15:25, Staffan Larsen wrote: > > Good point! > > new webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.02/ > > Thanks, > /Staffan > >> On 16 feb 2015, at 12:40, Remi Forax wrote: >> >> Hi Staffan, >> ASM MethodVisitor API requires to call visitAnnotation before calling visitCode so >> I think you shoud call visitAnnotation before calling new ForwardingMethodGenerator(mv).generate(). >> >> cheers, >> R?mi >> >> On 02/16/2015 08:47 AM, Staffan Larsen wrote: >>> Brian pointed out to me that this change missed to add the annotation to bridge methods. Here is an updated version that takes those into account. I also needed to update the test to verify that bridge methods were correctly annotated - it got a little bit more complex since I had to force bridges being used. >>> >>> new webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.01/ >>> >>> Thanks, >>> /Staffan >>> >>> >>>> On 3 feb 2015, at 10:15, Staffan Larsen wrote: >>>> >>>> Hi, >>>> >>>> Please review this patch for hiding the lambda proxy frame in stack traces: >>>> >>>> bug: https://bugs.openjdk.java.net/browse/JDK-8025636 >>>> webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.00/ >>>> >>>> This is a straightforward addition of the LambdaForm$Hidden annotation to the generated methods. What is surprising is that this works even if LambdaForm$Hidden is a package-private class in java.lang.invoke and thus not accessible from most of the generated classes. There is some discussion of and answers to this in the bug, but essentially this works because the annotation class is never resolved and the code in Hotspot that looks for the annotation amounts to nothing more than string comparisons. >>>> >>>> Hidden stack frames can be shown by running with ?-XX:+UnlockDiagnosticVMOptions -XX:+ShowHiddenFrames?. >>>> >>>> For an example of what this patch does, consider this code: >>>> >>>> Runnable r = () -> { throw new RuntimeException(); }; >>>> r.run(); >>>> >>>> Previously, this would output: >>>> >>>> java.lang.RuntimeException >>>> at pkg.Foo.lambda$main$0(Foo.java:5) >>>> at pkg.Foo$$Lambda$1/2001112025.run(:1000000) >>>> at pkg.Foo.main(Foo.java:15) >>>> >>>> With the patch it looks like this: >>>> >>>> java.lang.RuntimeException >>>> at pkg.Foo.lambda$main$0(Foo.java:5) >>>> at pkg.Foo.main(Foo.java:15) >>>> >>>> >>>> Thanks, >>>> /Staffan >>>> >>> >> > From maurizio.cimadamore at oracle.com Mon Feb 16 19:27:40 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 16 Feb 2015 19:27:40 +0000 Subject: javac 8/9 inconsistency In-Reply-To: <00af01d04a10$6ad26590$407730b0$@jetbrains.com> References: <00af01d04a10$6ad26590$407730b0$@jetbrains.com> Message-ID: <54E244AC.3070408@oracle.com> Hi Anna, it looks like the test should compile - I'm not sure as to which bugs are involved, I'll take a closer look and let you know. Thanks Maurizio On 16/02/15 17:45, Anna Kozlova wrote: > > Hi, > > The following code compiles with java 9 (b. 49) but doesn?t with 8 > (1.8u40 b.23) > > class Test { > > public static void foo(Test test) { > > Test e = create(Test::factory, test); > > } > > private static T create(Supplier callback, T defaultVal) { > > return null; > > } > > static

Test

factory() { > > return null; > > } > > } > > What is correct? > > BTW I?ve found https://bugs.openjdk.java.net/browse/JDK-8055963 which > explains to me the situation withTest e = create(() -> > factory(), test); but the fix version is 9. Would it be backported to > java 8? > > Thank you, > > Anna > -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Mon Feb 16 19:28:24 2015 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Mon, 16 Feb 2015 20:28:24 +0100 Subject: RFR: JDK-8025636 Hide lambda proxy frames in stacktraces In-Reply-To: <51071589-360E-4ECA-959C-FDF95AE70AB0@oracle.com> References: <54E1D71A.1080906@univ-mlv.fr> <7AE8811E-F669-480E-AD91-8300561BD8B7@oracle.com> <51071589-360E-4ECA-959C-FDF95AE70AB0@oracle.com> Message-ID: <8E31A5A6-FAE7-4D74-AFD4-896A0FBD466F@univ-mlv.fr> yes, thumb up ! R?mi Le 16 f?vrier 2015 18:50:25 CET, "Joel Borggr?n-Franck" a ?crit : >+1 > >cheers >/Joel > >> On 16 Feb 2015, at 15:25, Staffan Larsen >wrote: >> >> Good point! >> >> new webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.02/ >> >> Thanks, >> /Staffan >> >>> On 16 feb 2015, at 12:40, Remi Forax wrote: >>> >>> Hi Staffan, >>> ASM MethodVisitor API requires to call visitAnnotation before >calling visitCode so >>> I think you shoud call visitAnnotation before calling new >ForwardingMethodGenerator(mv).generate(). >>> >>> cheers, >>> R?mi >>> >>> On 02/16/2015 08:47 AM, Staffan Larsen wrote: >>>> Brian pointed out to me that this change missed to add the >annotation to bridge methods. Here is an updated version that takes >those into account. I also needed to update the test to verify that >bridge methods were correctly annotated - it got a little bit more >complex since I had to force bridges being used. >>>> >>>> new webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.01/ >>>> >>>> Thanks, >>>> /Staffan >>>> >>>> >>>>> On 3 feb 2015, at 10:15, Staffan Larsen > wrote: >>>>> >>>>> Hi, >>>>> >>>>> Please review this patch for hiding the lambda proxy frame in >stack traces: >>>>> >>>>> bug: https://bugs.openjdk.java.net/browse/JDK-8025636 >>>>> webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.00/ >>>>> >>>>> This is a straightforward addition of the LambdaForm$Hidden >annotation to the generated methods. What is surprising is that this >works even if LambdaForm$Hidden is a package-private class in >java.lang.invoke and thus not accessible from most of the generated >classes. There is some discussion of and answers to this in the bug, >but essentially this works because the annotation class is never >resolved and the code in Hotspot that looks for the annotation amounts >to nothing more than string comparisons. >>>>> >>>>> Hidden stack frames can be shown by running with >?-XX:+UnlockDiagnosticVMOptions -XX:+ShowHiddenFrames?. >>>>> >>>>> For an example of what this patch does, consider this code: >>>>> >>>>> Runnable r = () -> { throw new RuntimeException(); }; >>>>> r.run(); >>>>> >>>>> Previously, this would output: >>>>> >>>>> java.lang.RuntimeException >>>>> at pkg.Foo.lambda$main$0(Foo.java:5) >>>>> at pkg.Foo$$Lambda$1/2001112025.run(:1000000) >>>>> at pkg.Foo.main(Foo.java:15) >>>>> >>>>> With the patch it looks like this: >>>>> >>>>> java.lang.RuntimeException >>>>> at pkg.Foo.lambda$main$0(Foo.java:5) >>>>> at pkg.Foo.main(Foo.java:15) >>>>> >>>>> >>>>> Thanks, >>>>> /Staffan >>>>> >>>> >>> >> -- Envoy? de mon t?l?phone Android avec K-9 Mail. Excusez la bri?vet?. From john.r.rose at oracle.com Tue Feb 17 01:16:38 2015 From: john.r.rose at oracle.com (John Rose) Date: Mon, 16 Feb 2015 17:16:38 -0800 Subject: RFR: JDK-8025636 Hide lambda proxy frames in stacktraces In-Reply-To: <7AE8811E-F669-480E-AD91-8300561BD8B7@oracle.com> References: <54E1D71A.1080906@univ-mlv.fr> <7AE8811E-F669-480E-AD91-8300561BD8B7@oracle.com> Message-ID: <313ABEF2-036C-4E7F-A15D-F3240E417629@oracle.com> On Feb 16, 2015, at 6:25 AM, Staffan Larsen wrote: > > new webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.02/ Looks good; ship it. To me this fix raises more questions: 1. Are there other places where we generate ACC_SYNTHETIC that should also get @Hidden annotations? 2. Should the JVM be filtering stack frames for ACC_SYNTHETIC (or ACC_BRIDGE or ACC_MANDATED) calls? (By default? Or perhaps as a new option?) 3. When will we have a reasonable stack walking mechanism where we can program such policies in JDK library code, instead of hacking the JVM? ? John P.S. https://bugs.openjdk.java.net/browse/JDK-8043814 -------------- next part -------------- An HTML attachment was scrubbed... URL: From staffan.larsen at oracle.com Tue Feb 17 06:33:14 2015 From: staffan.larsen at oracle.com (Staffan Larsen) Date: Tue, 17 Feb 2015 07:33:14 +0100 Subject: RFR: JDK-8025636 Hide lambda proxy frames in stacktraces In-Reply-To: <313ABEF2-036C-4E7F-A15D-F3240E417629@oracle.com> References: <54E1D71A.1080906@univ-mlv.fr> <7AE8811E-F669-480E-AD91-8300561BD8B7@oracle.com> <313ABEF2-036C-4E7F-A15D-F3240E417629@oracle.com> Message-ID: <3CB05A58-C466-4F91-A405-694F2ADDA401@oracle.com> > On 17 feb 2015, at 02:16, John Rose wrote: > > On Feb 16, 2015, at 6:25 AM, Staffan Larsen > wrote: >> >> new webrev: http://cr.openjdk.java.net/~sla/8025636/webrev.02/ > Looks good; ship it. Thanks. > > To me this fix raises more questions: > > 1. Are there other places where we generate ACC_SYNTHETIC that should also get @Hidden annotations? > > 2. Should the JVM be filtering stack frames for ACC_SYNTHETIC (or ACC_BRIDGE or ACC_MANDATED) calls? (By default? Or perhaps as a new option?) The first shot at fixing this bug was to filter out ACC_SYNTHETIC. The drawback was that the actual lambda method are marked ACC_SYNTHETIC, so that filtered too much. /Staffan > > 3. When will we have a reasonable stack walking mechanism where we can program such policies in JDK library code, instead of hacking the JVM? > > ? John > > P.S. https://bugs.openjdk.java.net/browse/JDK-8043814 -------------- next part -------------- An HTML attachment was scrubbed... URL: From john.r.rose at oracle.com Tue Feb 17 06:54:20 2015 From: john.r.rose at oracle.com (John Rose) Date: Mon, 16 Feb 2015 22:54:20 -0800 Subject: RFR: JDK-8025636 Hide lambda proxy frames in stacktraces In-Reply-To: <3CB05A58-C466-4F91-A405-694F2ADDA401@oracle.com> References: <54E1D71A.1080906@univ-mlv.fr> <7AE8811E-F669-480E-AD91-8300561BD8B7@oracle.com> <313ABEF2-036C-4E7F-A15D-F3240E417629@oracle.com> <3CB05A58-C466-4F91-A405-694F2ADDA401@oracle.com> Message-ID: <364AD047-000F-4A98-951A-9D33937DFA1E@oracle.com> On Feb 16, 2015, at 10:33 PM, Staffan Larsen wrote: > > The first shot at fixing this bug was to filter out ACC_SYNTHETIC. The drawback was that the actual lambda method are marked ACC_SYNTHETIC, so that filtered too much. OTOH it seems odd to filter out the actual interface method. Ideally the back trace should show the name of the interface method and the implementation code of the lambda. This information is divided between the two frames in question. From maurizio.cimadamore at oracle.com Tue Feb 17 11:05:11 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 17 Feb 2015 11:05:11 +0000 Subject: javac 8/9 inconsistency In-Reply-To: <54E244AC.3070408@oracle.com> References: <00af01d04a10$6ad26590$407730b0$@jetbrains.com> <54E244AC.3070408@oracle.com> Message-ID: <54E32067.6050606@oracle.com> Hi Anna, I remember now - this is indeed: https://bugs.openjdk.java.net/browse/JDK-8055963 That problem was ultimately caused by an ambiguity in the spec - which is why the fix was targeted for 9 and hasn't been backported. I would say it's normal for these kind of spec-related fixes to target the next release and not being backported. Maurizio On 16/02/15 19:27, Maurizio Cimadamore wrote: > Hi Anna, > it looks like the test should compile - I'm not sure as to which bugs > are involved, I'll take a closer look and let you know. > > Thanks > Maurizio > > On 16/02/15 17:45, Anna Kozlova wrote: >> >> Hi, >> >> The following code compiles with java 9 (b. 49) but doesn?t with 8 >> (1.8u40 b.23) >> >> class Test { >> >> public static void foo(Test test) { >> >> Test e = create(Test::factory, test); >> >> } >> >> private static T create(Supplier callback, T defaultVal) { >> >> return null; >> >> } >> >> static

Test

factory() { >> >> return null; >> >> } >> >> } >> >> What is correct? >> >> BTW I?ve found https://bugs.openjdk.java.net/browse/JDK-8055963 which >> explains to me the situation withTest e = create(() -> >> factory(), test); but the fix version is 9. Would it be backported to >> java 8? >> >> Thank you, >> >> Anna >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From anna.kozlova at jetbrains.com Tue Feb 17 12:59:45 2015 From: anna.kozlova at jetbrains.com (Anna Kozlova) Date: Tue, 17 Feb 2015 13:59:45 +0100 Subject: javac 8/9 inconsistency In-Reply-To: <54E32067.6050606@oracle.com> References: <00af01d04a10$6ad26590$407730b0$@jetbrains.com> <54E244AC.3070408@oracle.com> <54E32067.6050606@oracle.com> Message-ID: <010d01d04ab1$9b2f2790$d18d76b0$@jetbrains.com> Hi Maurizio, Test::factory is not exact, correct? Then when return type constraint is added, T has only one lower bound, so https://bugs.openjdk.java.net/browse/JDK-8055963 doesn?t apply as is. What can it be then? BTW I found more inconsistencies between 8/9 in our testdata, should I file them? Thanks, Anna From: Maurizio Cimadamore [mailto:maurizio.cimadamore at oracle.com] Sent: Tuesday, February 17, 2015 12:05 PM To: Anna Kozlova; compiler-dev at openjdk.java.net Subject: Re: javac 8/9 inconsistency Hi Anna, I remember now - this is indeed: https://bugs.openjdk.java.net/browse/JDK-8055963 That problem was ultimately caused by an ambiguity in the spec - which is why the fix was targeted for 9 and hasn't been backported. I would say it's normal for these kind of spec-related fixes to target the next release and not being backported. Maurizio On 16/02/15 19:27, Maurizio Cimadamore wrote: Hi Anna, it looks like the test should compile - I'm not sure as to which bugs are involved, I'll take a closer look and let you know. Thanks Maurizio On 16/02/15 17:45, Anna Kozlova wrote: Hi, The following code compiles with java 9 (b. 49) but doesn?t with 8 (1.8u40 b.23) class Test { public static void foo(Test test) { Test e = create(Test::factory, test); } private static T create(Supplier callback, T defaultVal) { return null; } static

Test

factory() { return null; } } What is correct? BTW I?ve found https://bugs.openjdk.java.net/browse/JDK-8055963 which explains to me the situation with Test e = create(() -> factory(), test); but the fix version is 9. Would it be backported to java 8? Thank you, Anna !DSPAM:35,54e3207822491380419189! -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Tue Feb 17 14:39:28 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 17 Feb 2015 14:39:28 +0000 Subject: javac 8/9 inconsistency In-Reply-To: <010d01d04ab1$9b2f2790$d18d76b0$@jetbrains.com> References: <00af01d04a10$6ad26590$407730b0$@jetbrains.com> <54E244AC.3070408@oracle.com> <54E32067.6050606@oracle.com> <010d01d04ab1$9b2f2790$d18d76b0$@jetbrains.com> Message-ID: <54E352A0.7070801@oracle.com> On 17/02/15 12:59, Anna Kozlova wrote: > > Hi Maurizio, > > Test::factory is not exact, correct? Then when return type constraint > is added, T has only one lower bound, so > https://bugs.openjdk.java.net/browse/JDK-8055963 doesn?t apply as is. > What can it be then? > This is an issue in javac - while javac does not consider Test::factory pertinent to applicability in the applicability inference step, it goes ahead and type-checks it ahead of the return type during invocation method inference. This means that javac sees two bounds, Test

and Test and that's why 8055963 applies again here. In other words, while performing 18.5.2, javac is adding constraints from an argument that is not pertinent to applicability in the very first section of 18.5.2 which says: "Let B_2 be the bound set produced by reduction in order to demonstrate that |m| is applicable in ?18.5.1 . (While it was necessary in ?18.5.1 to demonstrate that the inference variables in B_2 could be resolved, in order to establish applicability, the instantiations produced by this resolution step are /not/ considered part of B_2 .) " This is a bug - if the argument has been considered not pertinent to applicability - it should simply be left alone here (and then considered back after target-type is thrown into the mix). I will file a bug. Please keep such issues coming - it's probably useful for both parties to look at them. Maurizio > > BTW I found more inconsistencies between 8/9 in our testdata, should I > file them? > > Thanks, > > Anna > > *From:*Maurizio Cimadamore [mailto:maurizio.cimadamore at oracle.com] > *Sent:* Tuesday, February 17, 2015 12:05 PM > *To:* Anna Kozlova; compiler-dev at openjdk.java.net > *Subject:* Re: javac 8/9 inconsistency > > Hi Anna, > I remember now - this is indeed: > > https://bugs.openjdk.java.net/browse/JDK-8055963 > > That problem was ultimately caused by an ambiguity in the spec - which > is why the fix was targeted for 9 and hasn't been backported. I would > say it's normal for these kind of spec-related fixes to target the > next release and not being backported. > > Maurizio > > On 16/02/15 19:27, Maurizio Cimadamore wrote: > > Hi Anna, > it looks like the test should compile - I'm not sure as to which > bugs are involved, I'll take a closer look and let you know. > > Thanks > Maurizio > > On 16/02/15 17:45, Anna Kozlova wrote: > > Hi, > > The following code compiles with java 9 (b. 49) but doesn?t > with 8 (1.8u40 b.23) > > class Test { > > public static void foo(Test test) { > > Test e = create(Test::factory, test); > > } > > private static T create(Supplier callback, T defaultVal) { > > return null; > > } > > static

Test

factory() { > > return null; > > } > > } > > What is correct? > > BTW I?ve found > https://bugs.openjdk.java.net/browse/JDK-8055963 which > explains to me the situation withTest e = create(() -> > factory(), test); but the fix version is 9. Would it be > backported to java 8? > > Thank you, > > Anna > > > !DSPAM:35,54e3207822491380419189! > -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Tue Feb 17 15:01:21 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 17 Feb 2015 15:01:21 +0000 Subject: javac 8/9 inconsistency In-Reply-To: <54E352A0.7070801@oracle.com> References: <00af01d04a10$6ad26590$407730b0$@jetbrains.com> <54E244AC.3070408@oracle.com> <54E32067.6050606@oracle.com> <010d01d04ab1$9b2f2790$d18d76b0$@jetbrains.com> <54E352A0.7070801@oracle.com> Message-ID: <54E357C1.9020304@oracle.com> On 17/02/15 14:39, Maurizio Cimadamore wrote: > This is a bug - if the argument has been considered not pertinent to > applicability - it should simply be left alone here (and then > considered back after target-type is thrown into the mix). I will file > a bug. Please keep such issues coming - it's probably useful for both > parties to look at them. Expanding a bit on this - I believe the spec is saying that the following should result in error: import java.util.function.*; class Sup { } class Sub1 extends Sup { } class Sub2 extends Sup { } class Test { public static void foo(Test test) { Test e1 = create(Test::factory, test); //error Test e2 = create(s -> new Test(), test); //error } private static T create(Function callback, T defaultVal) { return null; } static Test factory(String s) { return null; } } While javac correctly compiles as it's getting two lower bounds and then doing eager instantiation with the lub of such bound parameterizations. Dan, do you agree? Honestly, it seems a bit gratuitous to reject such code - is there any fundamental reason as to why we cannot go ahead and type-check those arguments (even if they are not pertinent to applicability) that are not stuck on any input type-variable? Could this warrant some spec enhancement? Maurizio From peter.levart at gmail.com Tue Feb 17 16:27:14 2015 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 17 Feb 2015 17:27:14 +0100 Subject: RFR: JDK-8025636 Hide lambda proxy frames in stacktraces In-Reply-To: <364AD047-000F-4A98-951A-9D33937DFA1E@oracle.com> References: <54E1D71A.1080906@univ-mlv.fr> <7AE8811E-F669-480E-AD91-8300561BD8B7@oracle.com> <313ABEF2-036C-4E7F-A15D-F3240E417629@oracle.com> <3CB05A58-C466-4F91-A405-694F2ADDA401@oracle.com> <364AD047-000F-4A98-951A-9D33937DFA1E@oracle.com> Message-ID: <54E36BE2.7030105@gmail.com> On 02/17/2015 07:54 AM, John Rose wrote: > On Feb 16, 2015, at 10:33 PM, Staffan Larsen wrote: >> The first shot at fixing this bug was to filter out ACC_SYNTHETIC. The drawback was that the actual lambda method are marked ACC_SYNTHETIC, so that filtered too much. > OTOH it seems odd to filter out the actual interface method. > > Ideally the back trace should show the name of the interface method and the implementation code of the lambda. > > This information is divided between the two frames in question. That's right. Lambda method is special. It is synthetic, but contains user code. So perhaps lambda method could be annotated with a special annotation (@SyntheticName) to indicate that the name of the method is generated and not interesting, but it's code is written by a programmer and is interesting. If this info was included in the StackTraceElement, then printing the stack trace could merge the byte code location of such element with the class/method name of the subsequent element and print both in one line... The logic behind this is general: if a method name is generated and not interesting (the lambda method), then code calling such method must have been generated too and is consequently not interesting (the proxy method). Peter From forax at univ-mlv.fr Tue Feb 17 23:54:15 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 18 Feb 2015 00:54:15 +0100 Subject: RFR: JDK-8025636 Hide lambda proxy frames in stacktraces In-Reply-To: <364AD047-000F-4A98-951A-9D33937DFA1E@oracle.com> References: <54E1D71A.1080906@univ-mlv.fr> <7AE8811E-F669-480E-AD91-8300561BD8B7@oracle.com> <313ABEF2-036C-4E7F-A15D-F3240E417629@oracle.com> <3CB05A58-C466-4F91-A405-694F2ADDA401@oracle.com> <364AD047-000F-4A98-951A-9D33937DFA1E@oracle.com> Message-ID: <54E3D4A7.8080703@univ-mlv.fr> On 02/17/2015 07:54 AM, John Rose wrote: > On Feb 16, 2015, at 10:33 PM, Staffan Larsen wrote: >> The first shot at fixing this bug was to filter out ACC_SYNTHETIC. The drawback was that the actual lambda method are marked ACC_SYNTHETIC, so that filtered too much. > OTOH it seems odd to filter out the actual interface method. > > Ideally the back trace should show the name of the interface method and the implementation code of the lambda. > > This information is divided between the two frames in question. The compiler can be changed to append the name of the interface method when generating the static method corresponding to the lambda but usually the name of the abstract method is not a useful information because a functional interface is more a function type than a real interface. R?mi From maurizio.cimadamore at oracle.com Wed Feb 18 00:17:34 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 18 Feb 2015 00:17:34 +0000 Subject: RFR: JDK-8025636 Hide lambda proxy frames in stacktraces In-Reply-To: <54E3D4A7.8080703@univ-mlv.fr> References: <54E1D71A.1080906@univ-mlv.fr> <7AE8811E-F669-480E-AD91-8300561BD8B7@oracle.com> <313ABEF2-036C-4E7F-A15D-F3240E417629@oracle.com> <3CB05A58-C466-4F91-A405-694F2ADDA401@oracle.com> <364AD047-000F-4A98-951A-9D33937DFA1E@oracle.com> <54E3D4A7.8080703@univ-mlv.fr> Message-ID: <54E3DA1E.2010504@oracle.com> I think this work (which is good) underlines a general there for some kind of pluggable logic for converting a synthetic method name into something more useful for the reader and/or to manipulate stack trace elements (i.e. remove elements, fold 2-3 elements into a new one, etc.). Lambda methods are special, but so are bridge methods, accessors etc. I bet there is a meaningful representation for some (all?) of those which is different from the blob of bytes generated by javac. For instance, an accessor could name the owner and name of the accessed symbol, a bridge could name the bridged call, and so forth. The manipulation on the stack trace should probably be optional (i.e. there should be flag to control it, in case one would like to use the full stack info i.e. for debugging purposes). Long story short, I think there's a bigger theme in here. Some of the work done by Charles Nutter in the JRuby land seems also relevant. Maurizio On 17/02/15 23:54, Remi Forax wrote: > > On 02/17/2015 07:54 AM, John Rose wrote: >> On Feb 16, 2015, at 10:33 PM, Staffan Larsen >> wrote: >>> The first shot at fixing this bug was to filter out ACC_SYNTHETIC. >>> The drawback was that the actual lambda method are marked >>> ACC_SYNTHETIC, so that filtered too much. >> OTOH it seems odd to filter out the actual interface method. >> >> Ideally the back trace should show the name of the interface method >> and the implementation code of the lambda. >> >> This information is divided between the two frames in question. > > The compiler can be changed to append the name of the interface method > when generating the static method corresponding to the lambda but > usually the name of the abstract method is not a useful information > because a functional interface is more a function type than a real > interface. > > R?mi > From anna.kozlova at jetbrains.com Wed Feb 18 11:29:56 2015 From: anna.kozlova at jetbrains.com (Anna Kozlova) Date: Wed, 18 Feb 2015 12:29:56 +0100 Subject: javac 8/9 inconsistency In-Reply-To: <54E352A0.7070801@oracle.com> References: <00af01d04a10$6ad26590$407730b0$@jetbrains.com> <54E244AC.3070408@oracle.com> <54E32067.6050606@oracle.com> <010d01d04ab1$9b2f2790$d18d76b0$@jetbrains.com> <54E352A0.7070801@oracle.com> Message-ID: <002801d04b6e$39356230$aba02690$@jetbrains.com> Hi, Ok, the following code compiles with 1.8u40 but fails with java 9 abstract class FooBoo { { map((Class ann) -> getAnnotation(ann)); //error map(this::getAnnotation); //error } abstract A getAnnotation(Class annotationClass); abstract void map(Function, ? extends R> mapper); } Anna From: Maurizio Cimadamore [mailto:maurizio.cimadamore at oracle.com] Sent: Tuesday, February 17, 2015 3:39 PM To: Anna Kozlova; compiler-dev at openjdk.java.net Subject: Re: javac 8/9 inconsistency On 17/02/15 12:59, Anna Kozlova wrote: Hi Maurizio, Test::factory is not exact, correct? Then when return type constraint is added, T has only one lower bound, so https://bugs.openjdk.java.net/browse/JDK-8055963 doesn?t apply as is. What can it be then? This is an issue in javac - while javac does not consider Test::factory pertinent to applicability in the applicability inference step, it goes ahead and type-checks it ahead of the return type during invocation method inference. This means that javac sees two bounds, Test

and Test and that's why 8055963 applies again here. In other words, while performing 18.5.2, javac is adding constraints from an argument that is not pertinent to applicability in the very first section of 18.5.2 which says: "Let B2 be the bound set produced by reduction in order to demonstrate that m is applicable in ?18.5.1 . (While it was necessary in ?18.5.1 to demonstrate that the inference variables in B2 could be resolved, in order to establish applicability, the instantiations produced by this resolution step are not considered part of B2.) " This is a bug - if the argument has been considered not pertinent to applicability - it should simply be left alone here (and then considered back after target-type is thrown into the mix). I will file a bug. Please keep such issues coming - it's probably useful for both parties to look at them. Maurizio BTW I found more inconsistencies between 8/9 in our testdata, should I file them? Thanks, Anna From: Maurizio Cimadamore [mailto:maurizio.cimadamore at oracle.com] Sent: Tuesday, February 17, 2015 12:05 PM To: Anna Kozlova; compiler-dev at openjdk.java.net Subject: Re: javac 8/9 inconsistency Hi Anna, I remember now - this is indeed: https://bugs.openjdk.java.net/browse/JDK-8055963 That problem was ultimately caused by an ambiguity in the spec - which is why the fix was targeted for 9 and hasn't been backported. I would say it's normal for these kind of spec-related fixes to target the next release and not being backported. Maurizio On 16/02/15 19:27, Maurizio Cimadamore wrote: Hi Anna, it looks like the test should compile - I'm not sure as to which bugs are involved, I'll take a closer look and let you know. Thanks Maurizio On 16/02/15 17:45, Anna Kozlova wrote: Hi, The following code compiles with java 9 (b. 49) but doesn?t with 8 (1.8u40 b.23) class Test { public static void foo(Test test) { Test e = create(Test::factory, test); } private static T create(Supplier callback, T defaultVal) { return null; } static

Test

factory() { return null; } } What is correct? BTW I?ve found https://bugs.openjdk.java.net/browse/JDK-8055963 which explains to me the situation with Test e = create(() -> factory(), test); but the fix version is 9. Would it be backported to java 8? Thank you, Anna !DSPAM:35,54e352b8157502614018010! -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Wed Feb 18 13:03:23 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 18 Feb 2015 13:03:23 +0000 Subject: javac 8/9 inconsistency In-Reply-To: <002801d04b6e$39356230$aba02690$@jetbrains.com> References: <00af01d04a10$6ad26590$407730b0$@jetbrains.com> <54E244AC.3070408@oracle.com> <54E32067.6050606@oracle.com> <010d01d04ab1$9b2f2790$d18d76b0$@jetbrains.com> <54E352A0.7070801@oracle.com> <002801d04b6e$39356230$aba02690$@jetbrains.com> Message-ID: <54E48D9B.1070605@oracle.com> Hi Anna, this is an issue we know about; this is the master bug we use to keep track of such issues: https://bugs.openjdk.java.net/browse/JDK-8039214 We did a bit of back and forth on this and as a result there is a difference between JDK 8 and JDK 9. The end result will be that this code will compile on both, but the fix used in 8 will be (very) different form the one we'll do in 9. Maurizio On 18/02/15 11:29, Anna Kozlova wrote: > *abstract class *FooBoo{ > { > map((Class ann) -> getAnnotation(ann)); //error > map(*this*::getAnnotation);//error > } > > *abstract * A getAnnotation(Class annotationClass); > *abstract * *void *map(Function, ? > *extends *R> mapper); > } -------------- next part -------------- An HTML attachment was scrubbed... URL: From anna.kozlova at jetbrains.com Wed Feb 18 13:15:24 2015 From: anna.kozlova at jetbrains.com (Anna Kozlova) Date: Wed, 18 Feb 2015 14:15:24 +0100 Subject: javac 8/9 inconsistency In-Reply-To: <54E48D9B.1070605@oracle.com> References: <00af01d04a10$6ad26590$407730b0$@jetbrains.com> <54E244AC.3070408@oracle.com> <54E32067.6050606@oracle.com> <010d01d04ab1$9b2f2790$d18d76b0$@jetbrains.com> <54E352A0.7070801@oracle.com> <002801d04b6e$39356230$aba02690$@jetbrains.com> <54E48D9B.1070605@oracle.com> Message-ID: <006001d04b7c$f4c7ff40$de57fdc0$@jetbrains.com> Thanks, I?ve saw the issue but was not sure if this sample is covered. Is it possible to make javac print what bounds it has inferred, what constraints it has processed? Thanks, Anna From: Maurizio Cimadamore [mailto:maurizio.cimadamore at oracle.com] Sent: Wednesday, February 18, 2015 2:03 PM To: Anna Kozlova; compiler-dev at openjdk.java.net Subject: Re: javac 8/9 inconsistency Hi Anna, this is an issue we know about; this is the master bug we use to keep track of such issues: https://bugs.openjdk.java.net/browse/JDK-8039214 We did a bit of back and forth on this and as a result there is a difference between JDK 8 and JDK 9. The end result will be that this code will compile on both, but the fix used in 8 will be (very) different form the one we'll do in 9. Maurizio On 18/02/15 11:29, Anna Kozlova wrote: abstract class FooBoo { { map((Class ann) -> getAnnotation(ann)); //error map(this::getAnnotation); //error } abstract A getAnnotation(Class annotationClass); abstract void map(Function, ? extends R> mapper); } !DSPAM:35,54e48db771362090119686! -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Wed Feb 18 14:03:30 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 18 Feb 2015 14:03:30 +0000 Subject: javac 8/9 inconsistency In-Reply-To: <006001d04b7c$f4c7ff40$de57fdc0$@jetbrains.com> References: <00af01d04a10$6ad26590$407730b0$@jetbrains.com> <54E244AC.3070408@oracle.com> <54E32067.6050606@oracle.com> <010d01d04ab1$9b2f2790$d18d76b0$@jetbrains.com> <54E352A0.7070801@oracle.com> <002801d04b6e$39356230$aba02690$@jetbrains.com> <54E48D9B.1070605@oracle.com> <006001d04b7c$f4c7ff40$de57fdc0$@jetbrains.com> Message-ID: <54E49BB2.3030700@oracle.com> Use the option -XDdumpInferenceGraphsTo=

This will dump a sequence of .dot files into the specified folder (make sure to reduce the test case as much as possible to keep the output readable). Maurizio On 18/02/15 13:15, Anna Kozlova wrote: > > Thanks, I?ve saw the issue but was not sure if this sample is covered. > > Is it possible to make javac print what bounds it has inferred, what > constraints it has processed? > > Thanks, > > Anna > > *From:*Maurizio Cimadamore [mailto:maurizio.cimadamore at oracle.com] > *Sent:* Wednesday, February 18, 2015 2:03 PM > *To:* Anna Kozlova; compiler-dev at openjdk.java.net > *Subject:* Re: javac 8/9 inconsistency > > Hi Anna, > this is an issue we know about; this is the master bug we use to keep > track of such issues: > > https://bugs.openjdk.java.net/browse/JDK-8039214 > > We did a bit of back and forth on this and as a result there is a > difference between JDK 8 and JDK 9. The end result will be that this > code will compile on both, but the fix used in 8 will be (very) > different form the one we'll do in 9. > > Maurizio > > On 18/02/15 11:29, Anna Kozlova wrote: > > *abstract class *FooBoo{ > { > map((Class ann) -> getAnnotation(ann)); > //error > map(*this*::getAnnotation);//error > } > > *abstract * A getAnnotation(Class annotationClass); > *abstract * *void *map(Function, > ? *extends *R> mapper); > } > > > !DSPAM:35,54e48db771362090119686! > -------------- next part -------------- An HTML attachment was scrubbed... URL: From aleksey.shipilev at oracle.com Fri Feb 20 14:40:40 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Fri, 20 Feb 2015 17:40:40 +0300 Subject: RFR (S) 8073550 : java* tools: replace obj.getClass hacks with Assert.checkNonNull or Objects.requireNonNull Message-ID: <54E74768.3010008@oracle.com> Hi, Please review and sponsor the cleanup in langtools code: https://bugs.openjdk.java.net/browse/JDK-8073550 http://cr.openjdk.java.net/~shade/8073550/webrev.01/ It replaces the getClass "hacks" with either proper Asserts, or Objects.requireNonNull if Asserts are not available over the module boundaries. Thanks, -Aleksey. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From maurizio.cimadamore at oracle.com Sun Feb 22 21:22:14 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Sun, 22 Feb 2015 21:22:14 +0000 Subject: RFR (S) 8073550 : java* tools: replace obj.getClass hacks with Assert.checkNonNull or Objects.requireNonNull In-Reply-To: <54E74768.3010008@oracle.com> References: <54E74768.3010008@oracle.com> Message-ID: <54EA4886.8060403@oracle.com> Looks great - thanks, I will push it for you. Maurizio On 20/02/15 14:40, Aleksey Shipilev wrote: > Hi, > > Please review and sponsor the cleanup in langtools code: > https://bugs.openjdk.java.net/browse/JDK-8073550 > http://cr.openjdk.java.net/~shade/8073550/webrev.01/ > > It replaces the getClass "hacks" with either proper Asserts, or > Objects.requireNonNull if Asserts are not available over the module > boundaries. > > Thanks, > -Aleksey. > From maurizio.cimadamore at oracle.com Mon Feb 23 13:29:53 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 23 Feb 2015 13:29:53 +0000 Subject: RFR (S) 8073550 : java* tools: replace obj.getClass hacks with Assert.checkNonNull or Objects.requireNonNull In-Reply-To: <54EA4886.8060403@oracle.com> References: <54E74768.3010008@oracle.com> <54EA4886.8060403@oracle.com> Message-ID: <54EB2B51.50006@oracle.com> Hi Aleksey, I did a build/test run on your patch and we have 5 langtools regression failures - they seem to be caused by the fact that there is some infrastructure in either the tests or in the file manager hierarchy itself which assign special semantics to NPEs, so when you replace them with something else (AssertionError), those tests stop working. Here are the failing tests: Execution failed: `main' threw exception: java.lang.AssertionError tools/javac/T6351767.java: javax.tools.JavaCompilerTool.getStandardFileManager().list() treats directories as package tools/javac/api/6410643/T6410643.java: JSR 199: The method JavaCompilerTool.run fails to handle null arguments tools/javac/api/T6400205.java: getClassLoader(location) returns null if getLocation(location) returns null tools/javac/api/T6400207.java: JSR 199: JavaFileManager.list and unset location Execution failed: `main' threw exception: java.lang.reflect.InvocationTargetException tools/javadoc/api/basic/GetTask_OptionsTest.java: javadoc should have a javax.tools.Tool service provider Most of the failing tests show the following stack trace: java.lang.AssertionError at com.sun.tools.javac.util.Assert.error(Assert.java:125) at com.sun.tools.javac.util.Assert.checkNonNull(Assert.java:60) * at com.sun.tools.javac.util.BaseFileManager.nullCheck(BaseFileManager.java:434)* at com.sun.tools.javac.file.JavacFileManager.list(JavacFileManager.java:670) at T6351767.main(T6351767.java:45) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.sun.javatest.regtest.MainAction$SameVMRunnable.run(MainAction.java:776) at java.lang.Thread.run(Thread.java:745) I'm deferring this to Jon as his expertize on this area is much greater than mine. My feeling is that those are public facing methods, whose spec say that an NPE should occur in certain cases, so either we leave the code as is, or we replace it with Objects.requireNonNull (which correctly throws an NPE). Jon, what do you think? Maurizio On 22/02/15 21:22, Maurizio Cimadamore wrote: > Looks great - thanks, I will push it for you. > > Maurizio > > On 20/02/15 14:40, Aleksey Shipilev wrote: >> Hi, >> >> Please review and sponsor the cleanup in langtools code: >> https://bugs.openjdk.java.net/browse/JDK-8073550 >> http://cr.openjdk.java.net/~shade/8073550/webrev.01/ >> >> It replaces the getClass "hacks" with either proper Asserts, or >> Objects.requireNonNull if Asserts are not available over the module >> boundaries. >> >> Thanks, >> -Aleksey. >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Mon Feb 23 14:52:07 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 23 Feb 2015 14:52:07 +0000 Subject: RFR (S) 8073550 : java* tools: replace obj.getClass hacks with Assert.checkNonNull or Objects.requireNonNull In-Reply-To: <54EB2B51.50006@oracle.com> References: <54E74768.3010008@oracle.com> <54EA4886.8060403@oracle.com> <54EB2B51.50006@oracle.com> Message-ID: <54EB3E97.4020209@oracle.com> The attached path passes all tests. I did a scan over the original patch and used Objects.requireNonNull in all API-sensitive implementations. I still have some doubts, so I'd appreciated if somebody else could glance over the changes... Maurizio On 23/02/15 13:29, Maurizio Cimadamore wrote: > Hi Aleksey, > I did a build/test run on your patch and we have 5 langtools > regression failures - they seem to be caused by the fact that there is > some infrastructure in either the tests or in the file manager > hierarchy itself which assign special semantics to NPEs, so when you > replace them with something else (AssertionError), those tests stop > working. > > Here are the failing tests: > > Execution failed: `main' threw exception: java.lang.AssertionError > > tools/javac/T6351767.java: > javax.tools.JavaCompilerTool.getStandardFileManager().list() treats > directories as package > tools/javac/api/6410643/T6410643.java: JSR 199: The method > JavaCompilerTool.run fails to handle null arguments > tools/javac/api/T6400205.java: getClassLoader(location) returns > null if getLocation(location) returns null > tools/javac/api/T6400207.java: JSR 199: JavaFileManager.list and > unset location > > Execution failed: `main' threw exception: > java.lang.reflect.InvocationTargetException > > tools/javadoc/api/basic/GetTask_OptionsTest.java: javadoc should > have a javax.tools.Tool service provider > > > Most of the failing tests show the following stack trace: > > java.lang.AssertionError > at com.sun.tools.javac.util.Assert.error(Assert.java:125) > at com.sun.tools.javac.util.Assert.checkNonNull(Assert.java:60) > * at com.sun.tools.javac.util.BaseFileManager.nullCheck(BaseFileManager.java:434)* > at com.sun.tools.javac.file.JavacFileManager.list(JavacFileManager.java:670) > at T6351767.main(T6351767.java:45) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:498) > at com.sun.javatest.regtest.MainAction$SameVMRunnable.run(MainAction.java:776) > at java.lang.Thread.run(Thread.java:745) > > I'm deferring this to Jon as his expertize on this area is much > greater than mine. My feeling is that those are public facing methods, > whose spec say that an NPE should occur in certain cases, so either we > leave the code as is, or we replace it with Objects.requireNonNull > (which correctly throws an NPE). Jon, what do you think? > > Maurizio > > On 22/02/15 21:22, Maurizio Cimadamore wrote: >> Looks great - thanks, I will push it for you. >> >> Maurizio >> >> On 20/02/15 14:40, Aleksey Shipilev wrote: >>> Hi, >>> >>> Please review and sponsor the cleanup in langtools code: >>> https://bugs.openjdk.java.net/browse/JDK-8073550 >>> http://cr.openjdk.java.net/~shade/8073550/webrev.01/ >>> >>> It replaces the getClass "hacks" with either proper Asserts, or >>> Objects.requireNonNull if Asserts are not available over the module >>> boundaries. >>> >>> Thanks, >>> -Aleksey. >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: langtools-v2.patch Type: text/x-patch Size: 31968 bytes Desc: not available URL: From jonathan.gibbons at oracle.com Mon Feb 23 16:05:06 2015 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Mon, 23 Feb 2015 08:05:06 -0800 Subject: RFR (S) 8073550 : java* tools: replace obj.getClass hacks with Assert.checkNonNull or Objects.requireNonNull In-Reply-To: <54EB3E97.4020209@oracle.com> References: <54E74768.3010008@oracle.com> <54EA4886.8060403@oracle.com> <54EB2B51.50006@oracle.com> <54EB3E97.4020209@oracle.com> Message-ID: <54EB4FB2.7060002@oracle.com> Maurizio, I will review the revised patch. Given there is public API involved, has anyone run the corresponding TCK tests? -- Jon On 02/23/2015 06:52 AM, Maurizio Cimadamore wrote: > The attached path passes all tests. I did a scan over the original > patch and used Objects.requireNonNull in all API-sensitive > implementations. I still have some doubts, so I'd appreciated if > somebody else could glance over the changes... > > Maurizio > > On 23/02/15 13:29, Maurizio Cimadamore wrote: >> Hi Aleksey, >> I did a build/test run on your patch and we have 5 langtools >> regression failures - they seem to be caused by the fact that there >> is some infrastructure in either the tests or in the file manager >> hierarchy itself which assign special semantics to NPEs, so when you >> replace them with something else (AssertionError), those tests stop >> working. >> >> Here are the failing tests: >> >> Execution failed: `main' threw exception: java.lang.AssertionError >> >> tools/javac/T6351767.java: >> javax.tools.JavaCompilerTool.getStandardFileManager().list() treats >> directories as package >> tools/javac/api/6410643/T6410643.java: JSR 199: The method >> JavaCompilerTool.run fails to handle null arguments >> tools/javac/api/T6400205.java: getClassLoader(location) returns >> null if getLocation(location) returns null >> tools/javac/api/T6400207.java: JSR 199: JavaFileManager.list and >> unset location >> >> Execution failed: `main' threw exception: >> java.lang.reflect.InvocationTargetException >> >> tools/javadoc/api/basic/GetTask_OptionsTest.java: javadoc should >> have a javax.tools.Tool service provider >> >> >> Most of the failing tests show the following stack trace: >> >> java.lang.AssertionError >> at com.sun.tools.javac.util.Assert.error(Assert.java:125) >> at com.sun.tools.javac.util.Assert.checkNonNull(Assert.java:60) >> * at com.sun.tools.javac.util.BaseFileManager.nullCheck(BaseFileManager.java:434)* >> at com.sun.tools.javac.file.JavacFileManager.list(JavacFileManager.java:670) >> at T6351767.main(T6351767.java:45) >> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) >> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) >> at java.lang.reflect.Method.invoke(Method.java:498) >> at com.sun.javatest.regtest.MainAction$SameVMRunnable.run(MainAction.java:776) >> at java.lang.Thread.run(Thread.java:745) >> >> I'm deferring this to Jon as his expertize on this area is much >> greater than mine. My feeling is that those are public facing >> methods, whose spec say that an NPE should occur in certain cases, so >> either we leave the code as is, or we replace it with >> Objects.requireNonNull (which correctly throws an NPE). Jon, what do >> you think? >> >> Maurizio >> >> On 22/02/15 21:22, Maurizio Cimadamore wrote: >>> Looks great - thanks, I will push it for you. >>> >>> Maurizio >>> >>> On 20/02/15 14:40, Aleksey Shipilev wrote: >>>> Hi, >>>> >>>> Please review and sponsor the cleanup in langtools code: >>>> https://bugs.openjdk.java.net/browse/JDK-8073550 >>>> http://cr.openjdk.java.net/~shade/8073550/webrev.01/ >>>> >>>> It replaces the getClass "hacks" with either proper Asserts, or >>>> Objects.requireNonNull if Asserts are not available over the module >>>> boundaries. >>>> >>>> Thanks, >>>> -Aleksey. >>>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Mon Feb 23 16:06:27 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 23 Feb 2015 16:06:27 +0000 Subject: RFR (S) 8073550 : java* tools: replace obj.getClass hacks with Assert.checkNonNull or Objects.requireNonNull In-Reply-To: <54EB4FB2.7060002@oracle.com> References: <54E74768.3010008@oracle.com> <54EA4886.8060403@oracle.com> <54EB2B51.50006@oracle.com> <54EB3E97.4020209@oracle.com> <54EB4FB2.7060002@oracle.com> Message-ID: <54EB5003.6000003@oracle.com> On 23/02/15 16:05, Jonathan Gibbons wrote: > Maurizio, > > I will review the revised patch. > > Given there is public API involved, has anyone run the corresponding > TCK tests? I did - the JCK compiler tests have few failures (4) because of these issues. Maurizio > > -- Jon > > On 02/23/2015 06:52 AM, Maurizio Cimadamore wrote: >> The attached path passes all tests. I did a scan over the original >> patch and used Objects.requireNonNull in all API-sensitive >> implementations. I still have some doubts, so I'd appreciated if >> somebody else could glance over the changes... >> >> Maurizio >> >> On 23/02/15 13:29, Maurizio Cimadamore wrote: >>> Hi Aleksey, >>> I did a build/test run on your patch and we have 5 langtools >>> regression failures - they seem to be caused by the fact that there >>> is some infrastructure in either the tests or in the file manager >>> hierarchy itself which assign special semantics to NPEs, so when you >>> replace them with something else (AssertionError), those tests stop >>> working. >>> >>> Here are the failing tests: >>> >>> Execution failed: `main' threw exception: java.lang.AssertionError >>> >>> tools/javac/T6351767.java: >>> javax.tools.JavaCompilerTool.getStandardFileManager().list() treats >>> directories as package >>> tools/javac/api/6410643/T6410643.java: JSR 199: The method >>> JavaCompilerTool.run fails to handle null arguments >>> tools/javac/api/T6400205.java: getClassLoader(location) returns >>> null if getLocation(location) returns null >>> tools/javac/api/T6400207.java: JSR 199: JavaFileManager.list and >>> unset location >>> >>> Execution failed: `main' threw exception: >>> java.lang.reflect.InvocationTargetException >>> >>> tools/javadoc/api/basic/GetTask_OptionsTest.java: javadoc should >>> have a javax.tools.Tool service provider >>> >>> >>> Most of the failing tests show the following stack trace: >>> >>> java.lang.AssertionError >>> at com.sun.tools.javac.util.Assert.error(Assert.java:125) >>> at com.sun.tools.javac.util.Assert.checkNonNull(Assert.java:60) >>> * at com.sun.tools.javac.util.BaseFileManager.nullCheck(BaseFileManager.java:434)* >>> at com.sun.tools.javac.file.JavacFileManager.list(JavacFileManager.java:670) >>> at T6351767.main(T6351767.java:45) >>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >>> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) >>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) >>> at java.lang.reflect.Method.invoke(Method.java:498) >>> at com.sun.javatest.regtest.MainAction$SameVMRunnable.run(MainAction.java:776) >>> at java.lang.Thread.run(Thread.java:745) >>> >>> I'm deferring this to Jon as his expertize on this area is much >>> greater than mine. My feeling is that those are public facing >>> methods, whose spec say that an NPE should occur in certain cases, >>> so either we leave the code as is, or we replace it with >>> Objects.requireNonNull (which correctly throws an NPE). Jon, what do >>> you think? >>> >>> Maurizio >>> >>> On 22/02/15 21:22, Maurizio Cimadamore wrote: >>>> Looks great - thanks, I will push it for you. >>>> >>>> Maurizio >>>> >>>> On 20/02/15 14:40, Aleksey Shipilev wrote: >>>>> Hi, >>>>> >>>>> Please review and sponsor the cleanup in langtools code: >>>>> https://bugs.openjdk.java.net/browse/JDK-8073550 >>>>> http://cr.openjdk.java.net/~shade/8073550/webrev.01/ >>>>> >>>>> It replaces the getClass "hacks" with either proper Asserts, or >>>>> Objects.requireNonNull if Asserts are not available over the module >>>>> boundaries. >>>>> >>>>> Thanks, >>>>> -Aleksey. >>>>> >>>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From joel.franck at oracle.com Mon Feb 23 20:24:00 2015 From: joel.franck at oracle.com (=?utf-8?Q?Joel_Borggr=C3=A9n-Franck?=) Date: Mon, 23 Feb 2015 21:24:00 +0100 Subject: RFR and comments: 8031744: Annotations on many Language Model elements are not returned Message-ID: Hi, For a while now I have been working on refactoring the annotations handling code in javac, with the intent of cleaning up issues introduced with the merging of repeating annotations and improving support for type annotations in javax.lang.model. The work has been going on over in the anno-pipeline/dev forest at http://hg.openjdk.java.net/anno-pipeline/dev/langtools/ and I think the patch set has been stable enough for a while now to propose a merge. This quite large webrev addresses two issues that were hard to separate out to two distinct patches: 1) Simplify and remove the use of 2 queues for repeating annotations. This refactoring removes the need and use of queues for declaration annotations. It does this by attaching a new piece of metadata (Annotate.AnnotationTypeMetadata) to the ClassSymbols that represent the declaration of an annotation type. This metadata can then be queried when attributing/entering instances of annotations of that annotation type. This eliminates the need for the queues and I have refactored the pipeline for normal declaration annotations (including repeating annotations) to only use one queue. The observation here is that in order to determine if @Foo @Foo is valid, you need to look at the declaration of Foo, to see if it is annotated with @Repeatable and in that case you need to look at the annotation type the @Repeatable instance designates. Before this was handled with a second queue, now this is handled by a separate visitor that just annotates @Target and @Repeatable "just in time" without using the queues. Most of the refactoring in Annotate.java is to support this. 2) Improving support for type annotations in javax.lang.model. The second part is a number of changes to Type and Types in order to support type annotations on Type instances. Also, type annotation instances are actually being added to Type instances that are used in type checking. This is potentially quite intrusive as in some cases methods in Types depended on Type instances being == while now they will no longer be so. To see why, consider the annotated cast (@TA Object). Currently the fixes for javax.lang.model only work for types coming from source files, we are working on improving the support from classes read from the class path as well. I know this patch introduces a performance regression, even for code not using type annotations. The plan is to reduce this regression in future work. I don?t think we can eliminate it entirely, but we should be able to reduce the regression significantly at least for code not using type annotations. The patch has been through internal reviews and and I have been fortunate to have Werner Dietl of the checkers framework beta test and report many issues. But with a patch of this size there are certainly more bugs lurking, so more testing would be most welcome. Webrev here: http://cr.openjdk.java.net/~jfranck/8031744/webrev.00/ cheers /Joel From jonathan.gibbons at oracle.com Wed Feb 25 19:00:06 2015 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Wed, 25 Feb 2015 11:00:06 -0800 Subject: Annotated Type bugs in OpenJDK 8 In-Reply-To: References: Message-ID: <54EE1BB6.5010205@oracle.com> Forwarding to compiler-dev and type-annotations-dev bcc: jdk8u-dev And yes, the right people are seeing this message. -- Jon On 02/25/2015 10:02 AM, Joshua Humphries wrote: > Hey, all, > I'm want to contribute some fixes to JDK 8 Updates related to annotated > types in core reflection. > > After much pain, I finally got it to build on my Macbook. So now I'm ready > to tackle a patch. The issues I plan to address in this patch follow: > > - JDK-8057804 > - JDK-8057898 > - JDK-8058202 > - JDK-8066967 (marked > resolved as a dup of the one above, JDK-8058202, but really is *not* a > dup) > > I actually filed all of these back in September. Unfortunately, since I'm > not an OpenJDK author, I can't login and add more comments to any of thee > bugs or interact with the assignee through the bug dashboard :( > > They are all assigned to Joel Borggr?n-Franck -- so I hope you're on this > list and see this, Joel :) > > The biggest change is JDK-8057804 > , so I wanted to discuss > options of how to address it. > > To summarize: there is a glaring omission in the > java.lang.reflect.AnnotatedType interfaces: there is *no way* to get to the > annotations on a (non-static, inner) parameterized type's owner. > > The AnnotatedParameterizedType interface really *should *have a method such > as: > AnnotatedType getAnnotatedOwnerType(); > > Without it, there is *no way* to use core reflection to examine annotations > on the owner type. Such annotations are allowed, included in the class file > by the compiler, and available via the model and annotation mirror APIs > used by annotation processors. But they aren't available via core > reflection. > > I've experimented with adding this method, and I have things working in a > local development environment. But there are some nasty implications to > adding a method to an interface. I think there are three approaches that > can be taken: > > 1. Add the method to the interface. Do not supply a default > implementation (e.g. break compatibility). This would be very similar to > the action taken in Java 8 to add the #getAnnotatedBounds() method to the > TypeVariable interface. (Related: JDK-8062794 > ) > - If such an incompatible change were deemed acceptable, it is > unlikely that it would be done in a point release. So, if this > is the right > solution, it would probably need to be implemented in the JDK 9 project > instead of the JDK 8 Updates project > 2. Add the method to the interface. Supply a default implementation for > backwards compatibility. > - A "best effort" implementation could grab the corresponding > ParameterizedType's owner and wrap it an AnnotatedType that has no > annotations. But then we're quietly suppressing the fact that we've lost > any annotations actually present. > - Instead of supplying an incorrect implementation, perhaps a better > default would be to simply throw UnsupportedOperationException, kind of > like the default implementation added for Iterator#remove(). > 3. Add a new interface that extends AnnotatedParameterizedType and adds > the method. This has the downside of polluting the namespace with redundant > interfaces, solely for trying to maintain compatibility. (No future code > should ever really use AnnotatedParameterizedType, so this feels icky.) > > At the moment, I'm tempted to think that option #2 is the best, with the > default implementation being to throw. > > I was hoping for some feedback from folks on this list with goal of > arriving at a solution that would be accepted into the JDK 8 Update project. > > ---- > *Joshua Humphries* > joshua at bluegosling.com From jonathan.gibbons at oracle.com Wed Feb 25 23:02:25 2015 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Wed, 25 Feb 2015 15:02:25 -0800 Subject: RFR: 8054717: SJavac should track changes in the public apis of classpath classes! In-Reply-To: <20150212215046.GA6527@e6430> References: <20141127012617.GA17122@e6430> <20141204155932.GC28610@e6430> <20141211104528.GA18525@e6430> <20141215224906.GB6858@e6430> <20150212215046.GA6527@e6430> Message-ID: <54EE5481.7070605@oracle.com> On 02/12/2015 01:50 PM, Andreas Lundblad wrote: > + $1_JAVAC_FLAGS := -bootclasspath "/home/alundbla/bootcp" -classpath "$$($1_CLASSPATH)" I doubt that any change should contain references to your personal home directory. -- Jon From alex.buckley at oracle.com Wed Feb 25 23:18:31 2015 From: alex.buckley at oracle.com (Alex Buckley) Date: Wed, 25 Feb 2015 15:18:31 -0800 Subject: Annotated Type bugs in OpenJDK 8 In-Reply-To: <54EE1BB6.5010205@oracle.com> References: <54EE1BB6.5010205@oracle.com> Message-ID: <54EE5847.6000706@oracle.com> // compiler-dev is the correct list. type-annotations-dev is defunct. Regarding JDK-8057804, I agree that AnnotatedParameterizedType deserves a getAnnotatedOwnerType() method. Since adding this method involves changing the Java SE API, it will need to target JDK 9 and appear in the compatibility notes. As a practical matter, it is extremely unlikely that there now exist non-JDK implementations of AnnotatedParameterizedType, so I would go ahead with option 1 (no default method). However, Joe may have a different view (though the experience of adding default methods to Core Reflection in Java SE 8 did not turn out quite as expected, IIRC). Alex On 2/25/2015 11:00 AM, Jonathan Gibbons wrote: > Forwarding to compiler-dev and type-annotations-dev > bcc: jdk8u-dev > > And yes, the right people are seeing this message. > > -- Jon > > > On 02/25/2015 10:02 AM, Joshua Humphries wrote: >> Hey, all, >> I'm want to contribute some fixes to JDK 8 Updates related to annotated >> types in core reflection. >> >> After much pain, I finally got it to build on my Macbook. So now I'm >> ready >> to tackle a patch. The issues I plan to address in this patch follow: >> >> - JDK-8057804 >> - JDK-8057898 >> - JDK-8058202 >> - JDK-8066967 >> (marked >> resolved as a dup of the one above, JDK-8058202, but really is >> *not* a >> dup) >> >> I actually filed all of these back in September. Unfortunately, since I'm >> not an OpenJDK author, I can't login and add more comments to any of thee >> bugs or interact with the assignee through the bug dashboard :( >> >> They are all assigned to Joel Borggr?n-Franck -- so I hope you're on this >> list and see this, Joel :) >> >> The biggest change is JDK-8057804 >> , so I wanted to >> discuss >> options of how to address it. >> >> To summarize: there is a glaring omission in the >> java.lang.reflect.AnnotatedType interfaces: there is *no way* to get >> to the >> annotations on a (non-static, inner) parameterized type's owner. >> >> The AnnotatedParameterizedType interface really *should *have a method >> such >> as: >> AnnotatedType getAnnotatedOwnerType(); >> >> Without it, there is *no way* to use core reflection to examine >> annotations >> on the owner type. Such annotations are allowed, included in the class >> file >> by the compiler, and available via the model and annotation mirror APIs >> used by annotation processors. But they aren't available via core >> reflection. >> >> I've experimented with adding this method, and I have things working in a >> local development environment. But there are some nasty implications to >> adding a method to an interface. I think there are three approaches that >> can be taken: >> >> 1. Add the method to the interface. Do not supply a default >> implementation (e.g. break compatibility). This would be very >> similar to >> the action taken in Java 8 to add the #getAnnotatedBounds() method >> to the >> TypeVariable interface. (Related: JDK-8062794 >> ) >> - If such an incompatible change were deemed acceptable, it is >> unlikely that it would be done in a point release. So, if this >> is the right >> solution, it would probably need to be implemented in the JDK 9 >> project >> instead of the JDK 8 Updates project >> 2. Add the method to the interface. Supply a default >> implementation for >> backwards compatibility. >> - A "best effort" implementation could grab the corresponding >> ParameterizedType's owner and wrap it an AnnotatedType that has no >> annotations. But then we're quietly suppressing the fact that >> we've lost >> any annotations actually present. >> - Instead of supplying an incorrect implementation, perhaps a >> better >> default would be to simply throw UnsupportedOperationException, >> kind of >> like the default implementation added for Iterator#remove(). >> 3. Add a new interface that extends AnnotatedParameterizedType and >> adds >> the method. This has the downside of polluting the namespace with >> redundant >> interfaces, solely for trying to maintain compatibility. (No >> future code >> should ever really use AnnotatedParameterizedType, so this feels >> icky.) >> >> At the moment, I'm tempted to think that option #2 is the best, with the >> default implementation being to throw. >> >> I was hoping for some feedback from folks on this list with goal of >> arriving at a solution that would be accepted into the JDK 8 Update >> project. >> >> ---- >> *Joshua Humphries* >> joshua at bluegosling.com > From jonathan.gibbons at oracle.com Wed Feb 25 23:48:47 2015 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Wed, 25 Feb 2015 15:48:47 -0800 Subject: RFR (S) 8073550 : java* tools: replace obj.getClass hacks with Assert.checkNonNull or Objects.requireNonNull In-Reply-To: <54EB3E97.4020209@oracle.com> References: <54E74768.3010008@oracle.com> <54EA4886.8060403@oracle.com> <54EB2B51.50006@oracle.com> <54EB3E97.4020209@oracle.com> Message-ID: <54EE5F5F.3050209@oracle.com> There are a number of minor issues here. I'm reviewing the langtools-v2.patch file. 1. Perhaps because of the churn, a number of files now have a new unnecessary import. 2. A call of either Assert.checkNonNull(x); or Objects.requireNonNull(x); does not need an explanatory comment of "// null check" and such comments should be removed. I can understand why such comments might have been left by automated scripts; I don't understand why in a few places, such comments were newly added. 3. In general, we should not depend on the javac internal Assert mechanism outside of javac. 4. In some places where there are multiple checks, the old code used to do all the checks before using any of the checked values. That has been changed in a few places, and in one place could leave an open stream lying around. It would be better to preserve the original execution order. Here is the full list of comments: DocTreePath redundant import of Assert 102,103 redundant comments TreePath redundant import of Assert 62,63 redundant comments com.sun.tools.classfile.ClassReader com.sun.tools.classfile.* should not really depend on anything in com.sun.tools.javac.* In this case, I think Objects.requireNonNull is preferable better to do the check before opening input stream com.sun.tools.classfile.ClassFileDependencies com.sun.tools.classfile.* should not really depend on anything in com.sun.tools.javac.* In this case, I think Objects.requireNonNull is preferable ClientCodeWrapper NPE would be better than an assert failure, so Objects.checkNonNull would be better JavacScope redundant import, redundant comment in this instance AssertionError would be better; this is an internal method, and javac would be wrong to provide null here JavacTaskImpl redundant comment JavacTool, JavacFileManager, Locations, RegularFileObject redundant import, redundant comments ZipArchive redundant import PathFileObject redundant import, redundant comments BaseFileManager 434-436 remove (inline) unnecessary method JavahTask redundant imports AttributeWriter Previously, the code did two checks, and only if both are OK did the assigments happen. With the proposed check, one assignment might happen, but not the other. JavapTask redundant imports, redundant comment Content doclet internal class should not use javac internal class better to use Objects.requireNonNull, or remove (inline) the method Start doclet internal class should not use javac internal class better to use Objects.requireNonNull JavadocTool duplicate imports ----------------------------- -- Jon On 02/23/2015 06:52 AM, Maurizio Cimadamore wrote: > The attached path passes all tests. I did a scan over the original > patch and used Objects.requireNonNull in all API-sensitive > implementations. I still have some doubts, so I'd appreciated if > somebody else could glance over the changes... > > Maurizio > > On 23/02/15 13:29, Maurizio Cimadamore wrote: >> Hi Aleksey, >> I did a build/test run on your patch and we have 5 langtools >> regression failures - they seem to be caused by the fact that there >> is some infrastructure in either the tests or in the file manager >> hierarchy itself which assign special semantics to NPEs, so when you >> replace them with something else (AssertionError), those tests stop >> working. >> >> Here are the failing tests: >> >> Execution failed: `main' threw exception: java.lang.AssertionError >> >> tools/javac/T6351767.java: >> javax.tools.JavaCompilerTool.getStandardFileManager().list() treats >> directories as package >> tools/javac/api/6410643/T6410643.java: JSR 199: The method >> JavaCompilerTool.run fails to handle null arguments >> tools/javac/api/T6400205.java: getClassLoader(location) returns >> null if getLocation(location) returns null >> tools/javac/api/T6400207.java: JSR 199: JavaFileManager.list and >> unset location >> >> Execution failed: `main' threw exception: >> java.lang.reflect.InvocationTargetException >> >> tools/javadoc/api/basic/GetTask_OptionsTest.java: javadoc should >> have a javax.tools.Tool service provider >> >> >> Most of the failing tests show the following stack trace: >> >> java.lang.AssertionError >> at com.sun.tools.javac.util.Assert.error(Assert.java:125) >> at com.sun.tools.javac.util.Assert.checkNonNull(Assert.java:60) >> * at com.sun.tools.javac.util.BaseFileManager.nullCheck(BaseFileManager.java:434)* >> at com.sun.tools.javac.file.JavacFileManager.list(JavacFileManager.java:670) >> at T6351767.main(T6351767.java:45) >> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) >> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) >> at java.lang.reflect.Method.invoke(Method.java:498) >> at com.sun.javatest.regtest.MainAction$SameVMRunnable.run(MainAction.java:776) >> at java.lang.Thread.run(Thread.java:745) >> >> I'm deferring this to Jon as his expertize on this area is much >> greater than mine. My feeling is that those are public facing >> methods, whose spec say that an NPE should occur in certain cases, so >> either we leave the code as is, or we replace it with >> Objects.requireNonNull (which correctly throws an NPE). Jon, what do >> you think? >> >> Maurizio >> >> On 22/02/15 21:22, Maurizio Cimadamore wrote: >>> Looks great - thanks, I will push it for you. >>> >>> Maurizio >>> >>> On 20/02/15 14:40, Aleksey Shipilev wrote: >>>> Hi, >>>> >>>> Please review and sponsor the cleanup in langtools code: >>>> https://bugs.openjdk.java.net/browse/JDK-8073550 >>>> http://cr.openjdk.java.net/~shade/8073550/webrev.01/ >>>> >>>> It replaces the getClass "hacks" with either proper Asserts, or >>>> Objects.requireNonNull if Asserts are not available over the module >>>> boundaries. >>>> >>>> Thanks, >>>> -Aleksey. >>>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Thu Feb 26 00:25:07 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 26 Feb 2015 00:25:07 +0000 Subject: RFR (S) 8073550 : java* tools: replace obj.getClass hacks with Assert.checkNonNull or Objects.requireNonNull In-Reply-To: <54EE5F5F.3050209@oracle.com> References: <54E74768.3010008@oracle.com> <54EA4886.8060403@oracle.com> <54EB2B51.50006@oracle.com> <54EB3E97.4020209@oracle.com> <54EE5F5F.3050209@oracle.com> Message-ID: <54EE67E3.3070808@oracle.com> On 25/02/15 23:48, Jonathan Gibbons wrote: > There are a number of minor issues here. I'm reviewing the > langtools-v2.patch file. > > 1. Perhaps because of the churn, a number of files now have a new > unnecessary import. I'll clean those up > > 2. A call of either Assert.checkNonNull(x); or > Objects.requireNonNull(x); does not need an explanatory comment of "// > null check" and such comments should be removed. I can understand why > such comments might have been left by automated scripts; I don't > understand why in a few places, such comments were newly added. I was the one adding them - out of an attempt to make it explicit as to which checks were 'demanded' by the API. I can remove them no problem. > > 3. In general, we should not depend on the javac internal Assert > mechanism outside of javac. Uh - ok. Not sure I fully buy this - i.e. javadoc reuses 99% of javac so I'm not sure what buys us not to use Assert mechanism there... > > 4. In some places where there are multiple checks, the old code used > to do all the checks before using any of the checked values. That has > been changed in a few places, and in one place could leave an open > stream lying around. It would be better to preserve the original > execution order. Ouch - didn't spot those, thx. I will address the comments and post another webrev with a delta patch. Maurizio > > > Here is the full list of comments: > > DocTreePath > redundant import of Assert > 102,103 redundant comments > > TreePath > redundant import of Assert > 62,63 redundant comments > > com.sun.tools.classfile.ClassReader > com.sun.tools.classfile.* should not really depend on anything in > com.sun.tools.javac.* > In this case, I think Objects.requireNonNull is preferable > better to do the check before opening input stream > > com.sun.tools.classfile.ClassFileDependencies > com.sun.tools.classfile.* should not really depend on anything in > com.sun.tools.javac.* > In this case, I think Objects.requireNonNull is preferable > > ClientCodeWrapper > NPE would be better than an assert failure, so Objects.checkNonNull > would be better > > JavacScope > redundant import, redundant comment > in this instance AssertionError would be better; this is an > internal method, and javac would be wrong to provide null here > > JavacTaskImpl > redundant comment > > JavacTool, JavacFileManager, Locations, RegularFileObject > redundant import, redundant comments > > ZipArchive > redundant import > > PathFileObject > redundant import, redundant comments > > BaseFileManager > 434-436 remove (inline) unnecessary method > > JavahTask > redundant imports > > AttributeWriter > Previously, the code did two checks, and only if both are OK > did the assigments happen. With the proposed check, one > assignment might happen, but not the other. > > JavapTask > redundant imports, redundant comment > > Content > doclet internal class should not use javac internal class > better to use Objects.requireNonNull, or remove (inline) > the method > > Start > doclet internal class should not use javac internal class > better to use Objects.requireNonNull > > JavadocTool > duplicate imports > > > ----------------------------- > > -- Jon > > > > > > > > > > On 02/23/2015 06:52 AM, Maurizio Cimadamore wrote: >> The attached path passes all tests. I did a scan over the original >> patch and used Objects.requireNonNull in all API-sensitive >> implementations. I still have some doubts, so I'd appreciated if >> somebody else could glance over the changes... >> >> Maurizio >> >> On 23/02/15 13:29, Maurizio Cimadamore wrote: >>> Hi Aleksey, >>> I did a build/test run on your patch and we have 5 langtools >>> regression failures - they seem to be caused by the fact that there >>> is some infrastructure in either the tests or in the file manager >>> hierarchy itself which assign special semantics to NPEs, so when you >>> replace them with something else (AssertionError), those tests stop >>> working. >>> >>> Here are the failing tests: >>> >>> Execution failed: `main' threw exception: java.lang.AssertionError >>> >>> tools/javac/T6351767.java: >>> javax.tools.JavaCompilerTool.getStandardFileManager().list() treats >>> directories as package >>> tools/javac/api/6410643/T6410643.java: JSR 199: The method >>> JavaCompilerTool.run fails to handle null arguments >>> tools/javac/api/T6400205.java: getClassLoader(location) returns >>> null if getLocation(location) returns null >>> tools/javac/api/T6400207.java: JSR 199: JavaFileManager.list and >>> unset location >>> >>> Execution failed: `main' threw exception: >>> java.lang.reflect.InvocationTargetException >>> >>> tools/javadoc/api/basic/GetTask_OptionsTest.java: javadoc should >>> have a javax.tools.Tool service provider >>> >>> >>> Most of the failing tests show the following stack trace: >>> >>> java.lang.AssertionError >>> at com.sun.tools.javac.util.Assert.error(Assert.java:125) >>> at com.sun.tools.javac.util.Assert.checkNonNull(Assert.java:60) >>> * at com.sun.tools.javac.util.BaseFileManager.nullCheck(BaseFileManager.java:434)* >>> at com.sun.tools.javac.file.JavacFileManager.list(JavacFileManager.java:670) >>> at T6351767.main(T6351767.java:45) >>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >>> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) >>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) >>> at java.lang.reflect.Method.invoke(Method.java:498) >>> at com.sun.javatest.regtest.MainAction$SameVMRunnable.run(MainAction.java:776) >>> at java.lang.Thread.run(Thread.java:745) >>> >>> I'm deferring this to Jon as his expertize on this area is much >>> greater than mine. My feeling is that those are public facing >>> methods, whose spec say that an NPE should occur in certain cases, >>> so either we leave the code as is, or we replace it with >>> Objects.requireNonNull (which correctly throws an NPE). Jon, what do >>> you think? >>> >>> Maurizio >>> >>> On 22/02/15 21:22, Maurizio Cimadamore wrote: >>>> Looks great - thanks, I will push it for you. >>>> >>>> Maurizio >>>> >>>> On 20/02/15 14:40, Aleksey Shipilev wrote: >>>>> Hi, >>>>> >>>>> Please review and sponsor the cleanup in langtools code: >>>>> https://bugs.openjdk.java.net/browse/JDK-8073550 >>>>> http://cr.openjdk.java.net/~shade/8073550/webrev.01/ >>>>> >>>>> It replaces the getClass "hacks" with either proper Asserts, or >>>>> Objects.requireNonNull if Asserts are not available over the module >>>>> boundaries. >>>>> >>>>> Thanks, >>>>> -Aleksey. >>>>> >>>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jonathan.gibbons at oracle.com Thu Feb 26 00:43:11 2015 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Wed, 25 Feb 2015 16:43:11 -0800 Subject: RFR (S) 8073550 : java* tools: replace obj.getClass hacks with Assert.checkNonNull or Objects.requireNonNull In-Reply-To: <54EE67E3.3070808@oracle.com> References: <54E74768.3010008@oracle.com> <54EA4886.8060403@oracle.com> <54EB2B51.50006@oracle.com> <54EB3E97.4020209@oracle.com> <54EE5F5F.3050209@oracle.com> <54EE67E3.3070808@oracle.com> Message-ID: <54EE6C1F.2000909@oracle.com> On 02/25/2015 04:25 PM, Maurizio Cimadamore wrote: >> >> 3. In general, we should not depend on the javac internal Assert >> mechanism outside of javac. > Uh - ok. Not sure I fully buy this - i.e. javadoc reuses 99% of javac > so I'm not sure what buys us not to use Assert mechanism there... The com.sun.tools.classfile library is currently stand-alone, totally separate from javac. It has even been backported into JDK 6. It seems wrong/unnecessary to introduce a new dependency on a minor javac utility class. In separate, somewhat unrelated discussions, we have talked about doing more with the javac Assert mechanism, and possibly recording more of the execution environment, in a somewhat more formalized way. That would likely depend on support code in the javac Main program, where we catch and handle all the exceptions that might come out of the javac internals. javadoc does not share/reuse that part of javac. Separately, the ongoing cleanup of the javac doclet API (JEP 221: http://openjdk.java.net/jeps/221) will significantly reduce javadoc's need to access javac internal API. So, it's good to keep the dependencies down. -- Jon From maurizio.cimadamore at oracle.com Thu Feb 26 01:14:18 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 26 Feb 2015 01:14:18 +0000 Subject: RFR (S) 8073550 : java* tools: replace obj.getClass hacks with Assert.checkNonNull or Objects.requireNonNull In-Reply-To: <54EE6C1F.2000909@oracle.com> References: <54E74768.3010008@oracle.com> <54EA4886.8060403@oracle.com> <54EB2B51.50006@oracle.com> <54EB3E97.4020209@oracle.com> <54EE5F5F.3050209@oracle.com> <54EE67E3.3070808@oracle.com> <54EE6C1F.2000909@oracle.com> Message-ID: <54EE736A.90304@oracle.com> On 26/02/15 00:43, Jonathan Gibbons wrote: > > On 02/25/2015 04:25 PM, Maurizio Cimadamore wrote: >>> >>> 3. In general, we should not depend on the javac internal Assert >>> mechanism outside of javac. >> Uh - ok. Not sure I fully buy this - i.e. javadoc reuses 99% of javac >> so I'm not sure what buys us not to use Assert mechanism there... > > The com.sun.tools.classfile library is currently stand-alone, totally > separate from javac. It has even been backported into JDK 6. It > seems wrong/unnecessary to introduce a new dependency on a minor javac > utility class. > > In separate, somewhat unrelated discussions, we have talked about > doing more with the javac Assert mechanism, and possibly recording > more of the execution environment, in a somewhat more formalized way. > That would likely depend on support code in the javac Main program, > where we catch and handle all the exceptions that might come out of > the javac internals. javadoc does not share/reuse that part of javac. > > Separately, the ongoing cleanup of the javac doclet API (JEP 221: > http://openjdk.java.net/jeps/221) will significantly reduce javadoc's > need to access javac internal API. So, it's good to keep the > dependencies down. Good - will clean those up Maurizio > > -- Jon From joel.franck at oracle.com Thu Feb 26 07:50:43 2015 From: joel.franck at oracle.com (=?utf-8?Q?Joel_Borggr=C3=A9n-Franck?=) Date: Thu, 26 Feb 2015 08:50:43 +0100 Subject: Annotated Type bugs in OpenJDK 8 In-Reply-To: <54EE5847.6000706@oracle.com> References: <54EE1BB6.5010205@oracle.com> <54EE5847.6000706@oracle.com> Message-ID: <6470DE5A-712A-46EF-91E1-B09BA69037FB@oracle.com> Hi, Discussing the spec change here on compiler dev is fine, but for code reviews please use core-libs-dev at openjdk.java.net . As Alex writes, adding owner method would require a spec change and should go into 9. I would also target the equal/hashcode changes to 9. When I looked at this in September/October I came to the conclusion that a default method throwing UnsupportedOperationException is the best option, if someone has an external implementation UOE is nicer than the linkage error I assume would happen if someone calls the missing method. If there are no external implementations this would never be called. I made a pass at fixing some of the errors in September, but when it became clear this would be a 9 only fix the patch got stuck in my patch queue. Feel free to reuse or compare notes with http://cr.openjdk.java.net/~jfranck/8057804/annotated-owner.patch (I noticed it doesn?t add a default, but that should be easy to fix). I?m not sure why https://bugs.openjdk.java.net/browse/JDK-8066967 was closed. I reopened it, I?m not sure what the error is here, but if you have a fix, go for it. Also, make sure you sign the OCA, http://www.oracle.com/technetwork/community/oca-486395.html For the spec change we have an internal process to approve those. When you have fix with approved review and have all the paperwork signed someone on this list or core-libs-dev can help you go through that. That someone would normally be me, but I?m going on parental leave. Once the fix for https://bugs.openjdk.java.net/browse/JDK-8057898 and possibly https://bugs.openjdk.java.net/browse/JDK-8066967 are in 9 you can consider back porting them to 8u. cheers /Joel > On 26 feb 2015, at 00:18, Alex Buckley wrote: > > // compiler-dev is the correct list. type-annotations-dev is defunct. > > Regarding JDK-8057804, I agree that AnnotatedParameterizedType deserves a getAnnotatedOwnerType() method. Since adding this method involves changing the Java SE API, it will need to target JDK 9 and appear in the compatibility notes. > > As a practical matter, it is extremely unlikely that there now exist non-JDK implementations of AnnotatedParameterizedType, so I would go ahead with option 1 (no default method). However, Joe may have a different view (though the experience of adding default methods to Core Reflection in Java SE 8 did not turn out quite as expected, IIRC). >> On 02/25/2015 10:02 AM, Joshua Humphries wrote: >>> Hey, all, >>> I'm want to contribute some fixes to JDK 8 Updates related to annotated >>> types in core reflection. >>> >>> After much pain, I finally got it to build on my Macbook. So now I'm >>> ready >>> to tackle a patch. The issues I plan to address in this patch follow: >>> >>> - JDK-8057804 >>> - JDK-8057898 >>> - JDK-8058202 >>> - JDK-8066967 >>> (marked >>> resolved as a dup of the one above, JDK-8058202, but really is >>> *not* a >>> dup) >>> >>> I actually filed all of these back in September. Unfortunately, since I'm >>> not an OpenJDK author, I can't login and add more comments to any of thee >>> bugs or interact with the assignee through the bug dashboard :( >>> >>> They are all assigned to Joel Borggr?n-Franck -- so I hope you're on this >>> list and see this, Joel :) >>> >>> The biggest change is JDK-8057804 >>> , so I wanted to >>> discuss >>> options of how to address it. >>> >>> To summarize: there is a glaring omission in the >>> java.lang.reflect.AnnotatedType interfaces: there is *no way* to get >>> to the >>> annotations on a (non-static, inner) parameterized type's owner. >>> >>> The AnnotatedParameterizedType interface really *should *have a method >>> such >>> as: >>> AnnotatedType getAnnotatedOwnerType(); >>> >>> Without it, there is *no way* to use core reflection to examine >>> annotations >>> on the owner type. Such annotations are allowed, included in the class >>> file >>> by the compiler, and available via the model and annotation mirror APIs >>> used by annotation processors. But they aren't available via core >>> reflection. >>> >>> I've experimented with adding this method, and I have things working in a >>> local development environment. But there are some nasty implications to >>> adding a method to an interface. I think there are three approaches that >>> can be taken: >>> >>> 1. Add the method to the interface. Do not supply a default >>> implementation (e.g. break compatibility). This would be very >>> similar to >>> the action taken in Java 8 to add the #getAnnotatedBounds() method >>> to the >>> TypeVariable interface. (Related: JDK-8062794 >>> ) >>> - If such an incompatible change were deemed acceptable, it is >>> unlikely that it would be done in a point release. So, if this >>> is the right >>> solution, it would probably need to be implemented in the JDK 9 >>> project >>> instead of the JDK 8 Updates project >>> 2. Add the method to the interface. Supply a default >>> implementation for >>> backwards compatibility. >>> - A "best effort" implementation could grab the corresponding >>> ParameterizedType's owner and wrap it an AnnotatedType that has no >>> annotations. But then we're quietly suppressing the fact that >>> we've lost >>> any annotations actually present. >>> - Instead of supplying an incorrect implementation, perhaps a >>> better >>> default would be to simply throw UnsupportedOperationException, >>> kind of >>> like the default implementation added for Iterator#remove(). >>> 3. Add a new interface that extends AnnotatedParameterizedType and >>> adds >>> the method. This has the downside of polluting the namespace with >>> redundant >>> interfaces, solely for trying to maintain compatibility. (No >>> future code >>> should ever really use AnnotatedParameterizedType, so this feels >>> icky.) >>> >>> At the moment, I'm tempted to think that option #2 is the best, with the >>> default implementation being to throw. >>> >>> I was hoping for some feedback from folks on this list with goal of >>> arriving at a solution that would be accepted into the JDK 8 Update >>> project. >>> >>> ---- >>> *Joshua Humphries* >>> joshua at bluegosling.com >> From maurizio.cimadamore at oracle.com Thu Feb 26 11:13:26 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 26 Feb 2015 11:13:26 +0000 Subject: RFR (S) 8073550 : java* tools: replace obj.getClass hacks with Assert.checkNonNull or Objects.requireNonNull In-Reply-To: <54EE736A.90304@oracle.com> References: <54E74768.3010008@oracle.com> <54EA4886.8060403@oracle.com> <54EB2B51.50006@oracle.com> <54EB3E97.4020209@oracle.com> <54EE5F5F.3050209@oracle.com> <54EE67E3.3070808@oracle.com> <54EE6C1F.2000909@oracle.com> <54EE736A.90304@oracle.com> Message-ID: <54EEFFD6.1020207@oracle.com> New patch and delta diff against previous patch. All test pass. Thanks Maurizio On 26/02/15 01:14, Maurizio Cimadamore wrote: > > On 26/02/15 00:43, Jonathan Gibbons wrote: >> >> On 02/25/2015 04:25 PM, Maurizio Cimadamore wrote: >>>> >>>> 3. In general, we should not depend on the javac internal Assert >>>> mechanism outside of javac. >>> Uh - ok. Not sure I fully buy this - i.e. javadoc reuses 99% of >>> javac so I'm not sure what buys us not to use Assert mechanism there... >> >> The com.sun.tools.classfile library is currently stand-alone, totally >> separate from javac. It has even been backported into JDK 6. It >> seems wrong/unnecessary to introduce a new dependency on a minor >> javac utility class. >> >> In separate, somewhat unrelated discussions, we have talked about >> doing more with the javac Assert mechanism, and possibly recording >> more of the execution environment, in a somewhat more formalized way. >> That would likely depend on support code in the javac Main program, >> where we catch and handle all the exceptions that might come out of >> the javac internals. javadoc does not share/reuse that part of javac. >> >> Separately, the ongoing cleanup of the javac doclet API (JEP 221: >> http://openjdk.java.net/jeps/221) will significantly reduce javadoc's >> need to access javac internal API. So, it's good to keep the >> dependencies down. > Good - will clean those up > > Maurizio >> >> -- Jon > -------------- next part -------------- A non-text attachment was scrubbed... Name: delta-v2-v3.patch Type: text/x-patch Size: 17559 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: langtools-v3.patch Type: text/x-patch Size: 28911 bytes Desc: not available URL: From brian.goetz at oracle.com Thu Feb 26 18:44:57 2015 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 26 Feb 2015 13:44:57 -0500 Subject: RFR: JDK-8025636 Hide lambda proxy frames in stacktraces In-Reply-To: <313ABEF2-036C-4E7F-A15D-F3240E417629@oracle.com> References: <54E1D71A.1080906@univ-mlv.fr> <7AE8811E-F669-480E-AD91-8300561BD8B7@oracle.com> <313ABEF2-036C-4E7F-A15D-F3240E417629@oracle.com> Message-ID: <54EF69A9.1000200@oracle.com> > 1. Are there other places where we generate ACC_SYNTHETIC that should > also get @Hidden annotations? Compiler-generated bridge methods? From jonathan.gibbons at oracle.com Fri Feb 27 01:34:08 2015 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Thu, 26 Feb 2015 17:34:08 -0800 Subject: RFR (S) 8073550 : java* tools: replace obj.getClass hacks with Assert.checkNonNull or Objects.requireNonNull In-Reply-To: <54EEFFD6.1020207@oracle.com> References: <54E74768.3010008@oracle.com> <54EA4886.8060403@oracle.com> <54EB2B51.50006@oracle.com> <54EB3E97.4020209@oracle.com> <54EE5F5F.3050209@oracle.com> <54EE67E3.3070808@oracle.com> <54EE6C1F.2000909@oracle.com> <54EE736A.90304@oracle.com> <54EEFFD6.1020207@oracle.com> Message-ID: <54EFC990.6050002@oracle.com> Looks good to me. -- Jon On 02/26/2015 03:13 AM, Maurizio Cimadamore wrote: > New patch and delta diff against previous patch. All test pass. > > Thanks > Maurizio > > On 26/02/15 01:14, Maurizio Cimadamore wrote: >> >> On 26/02/15 00:43, Jonathan Gibbons wrote: >>> >>> On 02/25/2015 04:25 PM, Maurizio Cimadamore wrote: >>>>> >>>>> 3. In general, we should not depend on the javac internal Assert >>>>> mechanism outside of javac. >>>> Uh - ok. Not sure I fully buy this - i.e. javadoc reuses 99% of >>>> javac so I'm not sure what buys us not to use Assert mechanism >>>> there... >>> >>> The com.sun.tools.classfile library is currently stand-alone, >>> totally separate from javac. It has even been backported into JDK >>> 6. It seems wrong/unnecessary to introduce a new dependency on a >>> minor javac utility class. >>> >>> In separate, somewhat unrelated discussions, we have talked about >>> doing more with the javac Assert mechanism, and possibly recording >>> more of the execution environment, in a somewhat more formalized >>> way. That would likely depend on support code in the javac Main >>> program, where we catch and handle all the exceptions that might >>> come out of the javac internals. javadoc does not share/reuse that >>> part of javac. >>> >>> Separately, the ongoing cleanup of the javac doclet API (JEP 221: >>> http://openjdk.java.net/jeps/221) will significantly reduce >>> javadoc's need to access javac internal API. So, it's good to keep >>> the dependencies down. >> Good - will clean those up >> >> Maurizio >>> >>> -- Jon >> > From jan.lahoda at oracle.com Fri Feb 27 08:31:16 2015 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Fri, 27 Feb 2015 09:31:16 +0100 Subject: History data for "JDK-8058150: Compile for Specific Platform Version" Message-ID: <54F02B54.3030700@oracle.com> Hi, I have a question on JDK-8058150: "Compile for Specific Platform Version". To support compilation for older versions of the platform, javac will need some description of the APIs as they existed in the target platforms. For this, the current proposal is to use lib/ct.sym file (similar, but different, to the JDK 8 lib/ct.sym), containing classfiles of the older APIs. This file would be constructed at build time from a textual representation of the APIs stored in an OpenJDK repository (currently called ct.sym.txt). The current ct.sym.txt is a single file that contains APIs for all supported versions, reusing entries for multiple versions when needed. An alternative would be to use ct7.sym.txt for JDK 7 APIs, ct8.sym.txt for JDK 8 APIs, etc. Using a single file leads to a smaller total size (as it reuses entries where it can), but needs to be considerably changed when a new version is added or an obsolete version is removed. The size of the file is considerable: for the "ct.sym.txt" that represents APIs from OpenJDK 7 and 8, the size of the checked-out file in the working copy is (currently[2]) ~23MB, and inside the .hg directory, the file has ~1.7MB (Mercurial is apparently able to compress the ct.sym.txt file very well - but as all history is kept inside .hg directory, the size of the file inside the .hg directory increases when the ct.sym.txt is updated). [2] The size may change based on what is included/excluded - e.g. currently, private methods and fields are removed from classes before writing this file; including these would make the file bigger. Another alternative would be to partition the file into several smaller files - would be easier to grasp, but if the files would be too small, the compression would be worse (leading to bigger repositories). Currently, the proposal is to place the ct.sym.txt file into the top-level repository. A prototype of this feature is currently in the jdk9/sandbox forest, on branch JDK-8058150-branch. The current ct.sym.txt file is /make/data/symbols/ct.sym.txt. Are there any insights/comments on this? Would adding this file to the repositories be acceptable? Thanks go to Jon Gibbons, Joe Darcy, Alan Bateman and others for their comments on this so far. Thanks, Jan From maurizio.cimadamore at oracle.com Fri Feb 27 11:53:44 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 27 Feb 2015 11:53:44 +0000 Subject: RFR (S) 8073550 : java* tools: replace obj.getClass hacks with Assert.checkNonNull or Objects.requireNonNull In-Reply-To: <54EFC990.6050002@oracle.com> References: <54E74768.3010008@oracle.com> <54EA4886.8060403@oracle.com> <54EB2B51.50006@oracle.com> <54EB3E97.4020209@oracle.com> <54EE5F5F.3050209@oracle.com> <54EE67E3.3070808@oracle.com> <54EE6C1F.2000909@oracle.com> <54EE736A.90304@oracle.com> <54EEFFD6.1020207@oracle.com> <54EFC990.6050002@oracle.com> Message-ID: <54F05AC8.1050006@oracle.com> Pushed - thanks to Aleksey for contributing the patch and to Jon for reviewing it ;-) Maurizio On 27/02/15 01:34, Jonathan Gibbons wrote: > Looks good to me. > > -- Jon > > On 02/26/2015 03:13 AM, Maurizio Cimadamore wrote: >> New patch and delta diff against previous patch. All test pass. >> >> Thanks >> Maurizio >> >> On 26/02/15 01:14, Maurizio Cimadamore wrote: >>> >>> On 26/02/15 00:43, Jonathan Gibbons wrote: >>>> >>>> On 02/25/2015 04:25 PM, Maurizio Cimadamore wrote: >>>>>> >>>>>> 3. In general, we should not depend on the javac internal Assert >>>>>> mechanism outside of javac. >>>>> Uh - ok. Not sure I fully buy this - i.e. javadoc reuses 99% of >>>>> javac so I'm not sure what buys us not to use Assert mechanism >>>>> there... >>>> >>>> The com.sun.tools.classfile library is currently stand-alone, >>>> totally separate from javac. It has even been backported into JDK >>>> 6. It seems wrong/unnecessary to introduce a new dependency on a >>>> minor javac utility class. >>>> >>>> In separate, somewhat unrelated discussions, we have talked about >>>> doing more with the javac Assert mechanism, and possibly recording >>>> more of the execution environment, in a somewhat more formalized >>>> way. That would likely depend on support code in the javac Main >>>> program, where we catch and handle all the exceptions that might >>>> come out of the javac internals. javadoc does not share/reuse that >>>> part of javac. >>>> >>>> Separately, the ongoing cleanup of the javac doclet API (JEP 221: >>>> http://openjdk.java.net/jeps/221) will significantly reduce >>>> javadoc's need to access javac internal API. So, it's good to keep >>>> the dependencies down. >>> Good - will clean those up >>> >>> Maurizio >>>> >>>> -- Jon >>> >> > From aleksey.shipilev at oracle.com Fri Feb 27 11:55:20 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Fri, 27 Feb 2015 14:55:20 +0300 Subject: RFR (S) 8073550 : java* tools: replace obj.getClass hacks with Assert.checkNonNull or Objects.requireNonNull In-Reply-To: <54F05AC8.1050006@oracle.com> References: <54E74768.3010008@oracle.com> <54EA4886.8060403@oracle.com> <54EB2B51.50006@oracle.com> <54EB3E97.4020209@oracle.com> <54EE5F5F.3050209@oracle.com> <54EE67E3.3070808@oracle.com> <54EE6C1F.2000909@oracle.com> <54EE736A.90304@oracle.com> <54EEFFD6.1020207@oracle.com> <54EFC990.6050002@oracle.com> <54F05AC8.1050006@oracle.com> Message-ID: <54F05B28.7070501@oracle.com> Thanks guys! -Aleksey On 27.02.2015 14:53, Maurizio Cimadamore wrote: > Pushed - thanks to Aleksey for contributing the patch and to Jon for > reviewing it ;-) > > Maurizio > > On 27/02/15 01:34, Jonathan Gibbons wrote: >> Looks good to me. >> >> -- Jon >> >> On 02/26/2015 03:13 AM, Maurizio Cimadamore wrote: >>> New patch and delta diff against previous patch. All test pass. >>> >>> Thanks >>> Maurizio >>> >>> On 26/02/15 01:14, Maurizio Cimadamore wrote: >>>> >>>> On 26/02/15 00:43, Jonathan Gibbons wrote: >>>>> >>>>> On 02/25/2015 04:25 PM, Maurizio Cimadamore wrote: >>>>>>> >>>>>>> 3. In general, we should not depend on the javac internal Assert >>>>>>> mechanism outside of javac. >>>>>> Uh - ok. Not sure I fully buy this - i.e. javadoc reuses 99% of >>>>>> javac so I'm not sure what buys us not to use Assert mechanism >>>>>> there... >>>>> >>>>> The com.sun.tools.classfile library is currently stand-alone, >>>>> totally separate from javac. It has even been backported into JDK >>>>> 6. It seems wrong/unnecessary to introduce a new dependency on a >>>>> minor javac utility class. >>>>> >>>>> In separate, somewhat unrelated discussions, we have talked about >>>>> doing more with the javac Assert mechanism, and possibly recording >>>>> more of the execution environment, in a somewhat more formalized >>>>> way. That would likely depend on support code in the javac Main >>>>> program, where we catch and handle all the exceptions that might >>>>> come out of the javac internals. javadoc does not share/reuse that >>>>> part of javac. >>>>> >>>>> Separately, the ongoing cleanup of the javac doclet API (JEP 221: >>>>> http://openjdk.java.net/jeps/221) will significantly reduce >>>>> javadoc's need to access javac internal API. So, it's good to keep >>>>> the dependencies down. >>>> Good - will clean those up >>>> >>>> Maurizio >>>>> >>>>> -- Jon >>>> >>> >> > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From magnus.ihse.bursie at oracle.com Fri Feb 27 13:48:00 2015 From: magnus.ihse.bursie at oracle.com (Magnus Ihse Bursie) Date: Fri, 27 Feb 2015 14:48:00 +0100 Subject: History data for "JDK-8058150: Compile for Specific Platform Version" In-Reply-To: <54F02B54.3030700@oracle.com> References: <54F02B54.3030700@oracle.com> Message-ID: <54F07590.90509@oracle.com> Hi Jan, On 2015-02-27 09:31, Jan Lahoda wrote: > Hi, > > I have a question on JDK-8058150: "Compile for Specific Platform > Version". To support compilation for older versions of the platform, > javac will need some description of the APIs as they existed in the > target platforms. > > For this, the current proposal is to use lib/ct.sym file (similar, but > different, to the JDK 8 lib/ct.sym), containing classfiles of the > older APIs. This file would be constructed at build time from a > textual representation of the APIs stored in an OpenJDK repository > (currently called ct.sym.txt). > > The current ct.sym.txt is a single file that contains APIs for all > supported versions, reusing entries for multiple versions when needed. > An alternative would be to use ct7.sym.txt for JDK 7 APIs, ct8.sym.txt > for JDK 8 APIs, etc. Using a single file leads to a smaller total size > (as it reuses entries where it can), but needs to be considerably > changed when a new version is added or an obsolete version is removed. > > The size of the file is considerable: for the "ct.sym.txt" that > represents APIs from OpenJDK 7 and 8, the size of the checked-out file > in the working copy is (currently[2]) ~23MB, and inside the .hg > directory, the file has ~1.7MB (Mercurial is apparently able to > compress the ct.sym.txt file very well - but as all history is kept > inside .hg directory, the size of the file inside the .hg directory > increases when the ct.sym.txt is updated). In my opinion, the only size that matters here is in the .hg directory. If the workspace takes 23 MB more or less is a non-issue when a full forest clone is in the gigabyte range. But I don't think 1.7 MB extra for the top-level repo is much of a problem either. Since the top-level repo currently is so tiny, it will grow noticably in percentage. But compare this with hotspot/.hg on 67 MB or jdk/.hg on 351 MB. If you have a proper text format so future edits can be made as trivial diffs, then the mercurial storage will not grow noticable in the future either. > Another alternative would be to partition the file into several > smaller files - would be easier to grasp, but if the files would be > too small, the compression would be worse (leading to bigger > repositories). What is the actual difference? Having too large files can be burdensome on other tools as well, eg. if you open it (mistakenly or not) in a text editor. I would tend to prefer several smaller files than one huge. > Currently, the proposal is to place the ct.sym.txt file into the > top-level repository. A prototype of this feature is currently in the > jdk9/sandbox forest, on branch JDK-8058150-branch. The current > ct.sym.txt file is /make/data/symbols/ct.sym.txt. Sounds like a good place to put such a file. I assume it will be processed during building? /Magnus From jan.lahoda at oracle.com Fri Feb 27 15:58:07 2015 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Fri, 27 Feb 2015 16:58:07 +0100 Subject: History data for "JDK-8058150: Compile for Specific Platform Version" In-Reply-To: <54F07590.90509@oracle.com> References: <54F02B54.3030700@oracle.com> <54F07590.90509@oracle.com> Message-ID: <54F0940F.7060007@oracle.com> On 27.2.2015 14:48, Magnus Ihse Bursie wrote: > Hi Jan, > > On 2015-02-27 09:31, Jan Lahoda wrote: >> Hi, >> >> I have a question on JDK-8058150: "Compile for Specific Platform >> Version". To support compilation for older versions of the platform, >> javac will need some description of the APIs as they existed in the >> target platforms. >> >> For this, the current proposal is to use lib/ct.sym file (similar, but >> different, to the JDK 8 lib/ct.sym), containing classfiles of the >> older APIs. This file would be constructed at build time from a >> textual representation of the APIs stored in an OpenJDK repository >> (currently called ct.sym.txt). >> >> The current ct.sym.txt is a single file that contains APIs for all >> supported versions, reusing entries for multiple versions when needed. >> An alternative would be to use ct7.sym.txt for JDK 7 APIs, ct8.sym.txt >> for JDK 8 APIs, etc. Using a single file leads to a smaller total size >> (as it reuses entries where it can), but needs to be considerably >> changed when a new version is added or an obsolete version is removed. >> >> The size of the file is considerable: for the "ct.sym.txt" that >> represents APIs from OpenJDK 7 and 8, the size of the checked-out file >> in the working copy is (currently[2]) ~23MB, and inside the .hg >> directory, the file has ~1.7MB (Mercurial is apparently able to >> compress the ct.sym.txt file very well - but as all history is kept >> inside .hg directory, the size of the file inside the .hg directory >> increases when the ct.sym.txt is updated). > > In my opinion, the only size that matters here is in the .hg directory. > If the workspace takes 23 MB more or less is a non-issue when a full > forest clone is in the gigabyte range. But I don't think 1.7 MB extra > for the top-level repo is much of a problem either. Since the top-level > repo currently is so tiny, it will grow noticably in percentage. But > compare this with hotspot/.hg on 67 MB or jdk/.hg on 351 MB. Thanks. I also think the size inside the .hg folder is more important. > > If you have a proper text format so future edits can be made as trivial > diffs, then the mercurial storage will not grow noticable in the future > either. The file currently contains version numbers on most lines, so adding or removing a support for a platform version means a significant update to the file. I am thinking of some ways to limit that, though. > >> Another alternative would be to partition the file into several >> smaller files - would be easier to grasp, but if the files would be >> too small, the compression would be worse (leading to bigger >> repositories). > What is the actual difference? Having too large files can be burdensome > on other tools as well, eg. if you open it (mistakenly or not) in a text > editor. I would tend to prefer several smaller files than one huge. That depends on how is the file split up. Originally, I was thinking of having a file per package, but that produces (too) many small files - 797 files, the biggest one having ~650kB (in the working copy), consumes ~5.9MB total inside .hg. There was a proposal to have a single ct.sym file per each jar file on the bootclasspath (in the target platform), but this produces ~20MB (in the working copy) file for ct.sym, while the next biggest file is for nashorn.jar: ~1MB (in the working copy). This consumes ~1.7MB inside the .hg directory. I tried to split the big ct.sym.txt artificially at approximately 1MB, this leads to 23 files, and still consumes ~1.7MB inside the .hg directory. >> Currently, the proposal is to place the ct.sym.txt file into the >> top-level repository. A prototype of this feature is currently in the >> jdk9/sandbox forest, on branch JDK-8058150-branch. The current >> ct.sym.txt file is /make/data/symbols/ct.sym.txt. > Sounds like a good place to put such a file. I assume it will be > processed during building? Yes, the file is processed during build and the ct.sym file in produced into the "lib" directory. In my current prototype, I've tweaked the make/Images.gmk to do that: http://hg.openjdk.java.net/jdk9/sandbox/file/087692cc2663/make/Images.gmk (in the "ct.sym" section). Thanks for the comments, Jan > > /Magnus From magnus.ihse.bursie at oracle.com Fri Feb 27 16:35:10 2015 From: magnus.ihse.bursie at oracle.com (Magnus Ihse Bursie) Date: Fri, 27 Feb 2015 17:35:10 +0100 Subject: History data for "JDK-8058150: Compile for Specific Platform Version" In-Reply-To: <54F0940F.7060007@oracle.com> References: <54F02B54.3030700@oracle.com> <54F07590.90509@oracle.com> <54F0940F.7060007@oracle.com> Message-ID: <54F09CBE.200@oracle.com> On 2015-02-27 16:58, Jan Lahoda wrote: > On 27.2.2015 14:48, Magnus Ihse Bursie wrote: >> Hi Jan, >> >> On 2015-02-27 09:31, Jan Lahoda wrote: >>> Hi, >>> >>> I have a question on JDK-8058150: "Compile for Specific Platform >>> Version". To support compilation for older versions of the platform, >>> javac will need some description of the APIs as they existed in the >>> target platforms. >>> >>> For this, the current proposal is to use lib/ct.sym file (similar, but >>> different, to the JDK 8 lib/ct.sym), containing classfiles of the >>> older APIs. This file would be constructed at build time from a >>> textual representation of the APIs stored in an OpenJDK repository >>> (currently called ct.sym.txt). >>> >>> The current ct.sym.txt is a single file that contains APIs for all >>> supported versions, reusing entries for multiple versions when needed. >>> An alternative would be to use ct7.sym.txt for JDK 7 APIs, ct8.sym.txt >>> for JDK 8 APIs, etc. Using a single file leads to a smaller total size >>> (as it reuses entries where it can), but needs to be considerably >>> changed when a new version is added or an obsolete version is removed. >>> >>> The size of the file is considerable: for the "ct.sym.txt" that >>> represents APIs from OpenJDK 7 and 8, the size of the checked-out file >>> in the working copy is (currently[2]) ~23MB, and inside the .hg >>> directory, the file has ~1.7MB (Mercurial is apparently able to >>> compress the ct.sym.txt file very well - but as all history is kept >>> inside .hg directory, the size of the file inside the .hg directory >>> increases when the ct.sym.txt is updated). >> >> In my opinion, the only size that matters here is in the .hg directory. >> If the workspace takes 23 MB more or less is a non-issue when a full >> forest clone is in the gigabyte range. But I don't think 1.7 MB extra >> for the top-level repo is much of a problem either. Since the top-level >> repo currently is so tiny, it will grow noticably in percentage. But >> compare this with hotspot/.hg on 67 MB or jdk/.hg on 351 MB. > > Thanks. I also think the size inside the .hg folder is more important. > >> >> If you have a proper text format so future edits can be made as trivial >> diffs, then the mercurial storage will not grow noticable in the future >> either. > > The file currently contains version numbers on most lines, so adding > or removing a support for a platform version means a significant > update to the file. I am thinking of some ways to limit that, though. I peaked at your current solution. Is it possible to store the file as a baseline version (JDK 7, or however far back you want to go) and a set of deltas? Instead of like: header extends java/lang/Object flags 31 classAnnotations @Ljdk/Profile+Annotation;(value=I4) versions 78 method name descriptor ()V flags 8 versions 78 method name descriptor ()V flags 1 versions 8 method name getHostId descriptor ()Ljava/lang/String; flags 1 versions 7 Store it like: baseline-jdk7.sym.txt header extends java/lang/Object flags 31 classAnnotations @Ljdk/Profile+Annotation;(value=I4) method name descriptor ()V flags 8 jdk8.sym.txt +method name descriptor ()V flags 1 -method name getHostId descriptor ()Ljava/lang/String; flags 1 ? In fact, if it is not too expensive to generate this kind of file from the build, you could perhaps do it the other way round, and create a "baseline" for the current JDK just built, and just store the diffs to previous versions. (Although that might be a maintainence burden to make sure that these reverse diffs are up to date). > >> >>> Another alternative would be to partition the file into several >>> smaller files - would be easier to grasp, but if the files would be >>> too small, the compression would be worse (leading to bigger >>> repositories). >> What is the actual difference? Having too large files can be burdensome >> on other tools as well, eg. if you open it (mistakenly or not) in a text >> editor. I would tend to prefer several smaller files than one huge. > > That depends on how is the file split up. Originally, I was thinking > of having a file per package, but that produces (too) many small files > - 797 files, the biggest one having ~650kB (in the working copy), > consumes ~5.9MB total inside .hg. Can you match it to modules? I realize older JDKs has no module concept, but that sounds like it could be a reasonable number of reasonable sized chunks. /Magnus > > There was a proposal to have a single ct.sym file per each jar file on > the bootclasspath (in the target platform), but this produces ~20MB > (in the working copy) file for ct.sym, while the next biggest file is > for nashorn.jar: ~1MB (in the working copy). This consumes ~1.7MB > inside the .hg directory. > > I tried to split the big ct.sym.txt artificially at approximately 1MB, > this leads to 23 files, and still consumes ~1.7MB inside the .hg > directory. > >>> Currently, the proposal is to place the ct.sym.txt file into the >>> top-level repository. A prototype of this feature is currently in the >>> jdk9/sandbox forest, on branch JDK-8058150-branch. The current >>> ct.sym.txt file is /make/data/symbols/ct.sym.txt. >> Sounds like a good place to put such a file. I assume it will be >> processed during building? > > Yes, the file is processed during build and the ct.sym file in > produced into the "lib" directory. In my current prototype, I've > tweaked the make/Images.gmk to do that: > http://hg.openjdk.java.net/jdk9/sandbox/file/087692cc2663/make/Images.gmk > (in the "ct.sym" section). > > Thanks for the comments, > Jan > >> >> /Magnus From jonathan.gibbons at oracle.com Fri Feb 27 16:54:38 2015 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Fri, 27 Feb 2015 08:54:38 -0800 Subject: History data for "JDK-8058150: Compile for Specific Platform Version" In-Reply-To: <54F09CBE.200@oracle.com> References: <54F02B54.3030700@oracle.com> <54F07590.90509@oracle.com> <54F0940F.7060007@oracle.com> <54F09CBE.200@oracle.com> Message-ID: <54F0A14E.7080401@oracle.com> On 02/27/2015 08:35 AM, Magnus Ihse Bursie wrote: > On 2015-02-27 16:58, Jan Lahoda wrote: >> On 27.2.2015 14:48, Magnus Ihse Bursie wrote: >>> Hi Jan, >>> >>> On 2015-02-27 09:31, Jan Lahoda wrote: >>>> Hi, >>>> >>>> I have a question on JDK-8058150: "Compile for Specific Platform >>>> Version". To support compilation for older versions of the platform, >>>> javac will need some description of the APIs as they existed in the >>>> target platforms. >>>> >>>> For this, the current proposal is to use lib/ct.sym file (similar, but >>>> different, to the JDK 8 lib/ct.sym), containing classfiles of the >>>> older APIs. This file would be constructed at build time from a >>>> textual representation of the APIs stored in an OpenJDK repository >>>> (currently called ct.sym.txt). >>>> >>>> The current ct.sym.txt is a single file that contains APIs for all >>>> supported versions, reusing entries for multiple versions when needed. >>>> An alternative would be to use ct7.sym.txt for JDK 7 APIs, ct8.sym.txt >>>> for JDK 8 APIs, etc. Using a single file leads to a smaller total size >>>> (as it reuses entries where it can), but needs to be considerably >>>> changed when a new version is added or an obsolete version is removed. >>>> >>>> The size of the file is considerable: for the "ct.sym.txt" that >>>> represents APIs from OpenJDK 7 and 8, the size of the checked-out file >>>> in the working copy is (currently[2]) ~23MB, and inside the .hg >>>> directory, the file has ~1.7MB (Mercurial is apparently able to >>>> compress the ct.sym.txt file very well - but as all history is kept >>>> inside .hg directory, the size of the file inside the .hg directory >>>> increases when the ct.sym.txt is updated). >>> >>> In my opinion, the only size that matters here is in the .hg directory. >>> If the workspace takes 23 MB more or less is a non-issue when a full >>> forest clone is in the gigabyte range. But I don't think 1.7 MB extra >>> for the top-level repo is much of a problem either. Since the top-level >>> repo currently is so tiny, it will grow noticably in percentage. But >>> compare this with hotspot/.hg on 67 MB or jdk/.hg on 351 MB. >> >> Thanks. I also think the size inside the .hg folder is more important. >> >>> >>> If you have a proper text format so future edits can be made as trivial >>> diffs, then the mercurial storage will not grow noticable in the future >>> either. >> >> The file currently contains version numbers on most lines, so adding >> or removing a support for a platform version means a significant >> update to the file. I am thinking of some ways to limit that, though. > > I peaked at your current solution. Is it possible to store the file as > a baseline version (JDK 7, or however far back you want to go) and a > set of deltas? Instead of like: > header extends java/lang/Object flags 31 classAnnotations > @Ljdk/Profile+Annotation;(value=I4) versions 78 > method name descriptor ()V flags 8 versions 78 > method name descriptor ()V flags 1 versions 8 > method name getHostId descriptor ()Ljava/lang/String; flags 1 versions 7 > > Store it like: > baseline-jdk7.sym.txt > header extends java/lang/Object flags 31 classAnnotations > @Ljdk/Profile+Annotation;(value=I4) > method name descriptor ()V flags 8 > > jdk8.sym.txt > +method name descriptor ()V flags 1 > -method name getHostId descriptor ()Ljava/lang/String; flags 1 > > ? > > In fact, if it is not too expensive to generate this kind of file from > the build, you could perhaps do it the other way round, and create a > "baseline" for the current JDK just built, and just store the diffs to > previous versions. (Although that might be a maintainence burden to > make sure that these reverse diffs are up to date). > > >> >>> >>>> Another alternative would be to partition the file into several >>>> smaller files - would be easier to grasp, but if the files would be >>>> too small, the compression would be worse (leading to bigger >>>> repositories). >>> What is the actual difference? Having too large files can be burdensome >>> on other tools as well, eg. if you open it (mistakenly or not) in a >>> text >>> editor. I would tend to prefer several smaller files than one huge. >> >> That depends on how is the file split up. Originally, I was thinking >> of having a file per package, but that produces (too) many small >> files - 797 files, the biggest one having ~650kB (in the working >> copy), consumes ~5.9MB total inside .hg. > Can you match it to modules? I realize older JDKs has no module > concept, but that sounds like it could be a reasonable number of > reasonable sized chunks. > > /Magnus > >> >> There was a proposal to have a single ct.sym file per each jar file >> on the bootclasspath (in the target platform), but this produces >> ~20MB (in the working copy) file for ct.sym, while the next biggest >> file is for nashorn.jar: ~1MB (in the working copy). This consumes >> ~1.7MB inside the .hg directory. >> >> I tried to split the big ct.sym.txt artificially at approximately >> 1MB, this leads to 23 files, and still consumes ~1.7MB inside the .hg >> directory. >> >>>> Currently, the proposal is to place the ct.sym.txt file into the >>>> top-level repository. A prototype of this feature is currently in the >>>> jdk9/sandbox forest, on branch JDK-8058150-branch. The current >>>> ct.sym.txt file is >>>> /make/data/symbols/ct.sym.txt. >>> Sounds like a good place to put such a file. I assume it will be >>> processed during building? >> >> Yes, the file is processed during build and the ct.sym file in >> produced into the "lib" directory. In my current prototype, I've >> tweaked the make/Images.gmk to do that: >> http://hg.openjdk.java.net/jdk9/sandbox/file/087692cc2663/make/Images.gmk >> >> (in the "ct.sym" section). >> >> Thanks for the comments, >> Jan >> >>> >>> /Magnus > Magnus, The simplified generalization of your suggestion would be to simply use patch/diff files. We could have a baseline of (say) jdk7.sym.txt then have a patch file jdk8.sym.patch which can be applied (in the build) to jdk7.sym.txt to get jdk8.sym.txt Since the .txt and .patch files reflect existing releases, they would almost never change, so the .hg files would be constant. Maybe once in a while, we would prune the history, remove older version info, and add a new baseline. -- Jon From jan.lahoda at oracle.com Fri Feb 27 16:56:31 2015 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Fri, 27 Feb 2015 17:56:31 +0100 Subject: History data for "JDK-8058150: Compile for Specific Platform Version" In-Reply-To: <54F09CBE.200@oracle.com> References: <54F02B54.3030700@oracle.com> <54F07590.90509@oracle.com> <54F0940F.7060007@oracle.com> <54F09CBE.200@oracle.com> Message-ID: <54F0A1BF.2030202@oracle.com> On 27.2.2015 17:35, Magnus Ihse Bursie wrote: > On 2015-02-27 16:58, Jan Lahoda wrote: >> On 27.2.2015 14:48, Magnus Ihse Bursie wrote: >>> Hi Jan, >>> >>> On 2015-02-27 09:31, Jan Lahoda wrote: >>>> Hi, >>>> >>>> I have a question on JDK-8058150: "Compile for Specific Platform >>>> Version". To support compilation for older versions of the platform, >>>> javac will need some description of the APIs as they existed in the >>>> target platforms. >>>> >>>> For this, the current proposal is to use lib/ct.sym file (similar, but >>>> different, to the JDK 8 lib/ct.sym), containing classfiles of the >>>> older APIs. This file would be constructed at build time from a >>>> textual representation of the APIs stored in an OpenJDK repository >>>> (currently called ct.sym.txt). >>>> >>>> The current ct.sym.txt is a single file that contains APIs for all >>>> supported versions, reusing entries for multiple versions when needed. >>>> An alternative would be to use ct7.sym.txt for JDK 7 APIs, ct8.sym.txt >>>> for JDK 8 APIs, etc. Using a single file leads to a smaller total size >>>> (as it reuses entries where it can), but needs to be considerably >>>> changed when a new version is added or an obsolete version is removed. >>>> >>>> The size of the file is considerable: for the "ct.sym.txt" that >>>> represents APIs from OpenJDK 7 and 8, the size of the checked-out file >>>> in the working copy is (currently[2]) ~23MB, and inside the .hg >>>> directory, the file has ~1.7MB (Mercurial is apparently able to >>>> compress the ct.sym.txt file very well - but as all history is kept >>>> inside .hg directory, the size of the file inside the .hg directory >>>> increases when the ct.sym.txt is updated). >>> >>> In my opinion, the only size that matters here is in the .hg directory. >>> If the workspace takes 23 MB more or less is a non-issue when a full >>> forest clone is in the gigabyte range. But I don't think 1.7 MB extra >>> for the top-level repo is much of a problem either. Since the top-level >>> repo currently is so tiny, it will grow noticably in percentage. But >>> compare this with hotspot/.hg on 67 MB or jdk/.hg on 351 MB. >> >> Thanks. I also think the size inside the .hg folder is more important. >> >>> >>> If you have a proper text format so future edits can be made as trivial >>> diffs, then the mercurial storage will not grow noticable in the future >>> either. >> >> The file currently contains version numbers on most lines, so adding >> or removing a support for a platform version means a significant >> update to the file. I am thinking of some ways to limit that, though. > > I peaked at your current solution. Is it possible to store the file as a > baseline version (JDK 7, or however far back you want to go) and a set > of deltas? Instead of like: > header extends java/lang/Object flags 31 classAnnotations > @Ljdk/Profile+Annotation;(value=I4) versions 78 > method name descriptor ()V flags 8 versions 78 > method name descriptor ()V flags 1 versions 8 > method name getHostId descriptor ()Ljava/lang/String; flags 1 versions 7 > > Store it like: > baseline-jdk7.sym.txt > header extends java/lang/Object flags 31 classAnnotations > @Ljdk/Profile+Annotation;(value=I4) > method name descriptor ()V flags 8 > > jdk8.sym.txt > +method name descriptor ()V flags 1 > -method name getHostId descriptor ()Ljava/lang/String; flags 1 > > ? I think this should be possible with the current format (IIRC this was suggested before, but the format at the time did not allow this). I'll try to see what would be the outcome. > > In fact, if it is not too expensive to generate this kind of file from > the build, you could perhaps do it the other way round, and create a > "baseline" for the current JDK just built, and just store the diffs to > previous versions. (Although that might be a maintainence burden to make > sure that these reverse diffs are up to date). Although I think this would be doable in principle, I would rather avoid this, to avoid the maintenance cost. > > >> >>> >>>> Another alternative would be to partition the file into several >>>> smaller files - would be easier to grasp, but if the files would be >>>> too small, the compression would be worse (leading to bigger >>>> repositories). >>> What is the actual difference? Having too large files can be burdensome >>> on other tools as well, eg. if you open it (mistakenly or not) in a text >>> editor. I would tend to prefer several smaller files than one huge. >> >> That depends on how is the file split up. Originally, I was thinking >> of having a file per package, but that produces (too) many small files >> - 797 files, the biggest one having ~650kB (in the working copy), >> consumes ~5.9MB total inside .hg. > Can you match it to modules? I realize older JDKs has no module concept, > but that sounds like it could be a reasonable number of reasonable sized > chunks. I'll try. Thanks, Jan > > /Magnus > >> >> There was a proposal to have a single ct.sym file per each jar file on >> the bootclasspath (in the target platform), but this produces ~20MB >> (in the working copy) file for ct.sym, while the next biggest file is >> for nashorn.jar: ~1MB (in the working copy). This consumes ~1.7MB >> inside the .hg directory. >> >> I tried to split the big ct.sym.txt artificially at approximately 1MB, >> this leads to 23 files, and still consumes ~1.7MB inside the .hg >> directory. >> >>>> Currently, the proposal is to place the ct.sym.txt file into the >>>> top-level repository. A prototype of this feature is currently in the >>>> jdk9/sandbox forest, on branch JDK-8058150-branch. The current >>>> ct.sym.txt file is /make/data/symbols/ct.sym.txt. >>> Sounds like a good place to put such a file. I assume it will be >>> processed during building? >> >> Yes, the file is processed during build and the ct.sym file in >> produced into the "lib" directory. In my current prototype, I've >> tweaked the make/Images.gmk to do that: >> http://hg.openjdk.java.net/jdk9/sandbox/file/087692cc2663/make/Images.gmk >> (in the "ct.sym" section). >> >> Thanks for the comments, >> Jan >> >>> >>> /Magnus >