From alejandro.murillo at oracle.com Mon Mar 3 18:07:28 2014 From: alejandro.murillo at oracle.com (alejandro.murillo at oracle.com) Date: Tue, 04 Mar 2014 02:07:28 +0000 Subject: hg: jdk8/jdk8/hotspot: 4 new changesets Message-ID: <20140304020737.2E6FF62482@hg.openjdk.java.net> Changeset: 54f0c207dc35 Author: amurillo Date: 2014-01-28 15:11 -0800 URL: http://hg.openjdk.java.net/jdk8/jdk8/hotspot/rev/54f0c207dc35 8032984: new hotspot build - hs25-b70 Reviewed-by: jcoomes ! make/hotspot_version Changeset: e46f2ee62e78 Author: vlivanov Date: 2014-03-03 16:10 -0800 URL: http://hg.openjdk.java.net/jdk8/jdk8/hotspot/rev/e46f2ee62e78 8036100: Default method returns true for a while, and then returns false Reviewed-by: kvn, jrose ! src/share/vm/ci/ciMethod.cpp + test/compiler/inlining/InlineDefaultMethod1.java Changeset: 9f9179e8f0cf Author: amurillo Date: 2014-03-03 17:48 -0800 URL: http://hg.openjdk.java.net/jdk8/jdk8/hotspot/rev/9f9179e8f0cf Merge Changeset: 0c94c41dcd70 Author: amurillo Date: 2014-03-03 17:48 -0800 URL: http://hg.openjdk.java.net/jdk8/jdk8/hotspot/rev/0c94c41dcd70 Added tag hs25-b70 for changeset 9f9179e8f0cf ! .hgtags From alejandro.murillo at oracle.com Mon Mar 3 18:29:13 2014 From: alejandro.murillo at oracle.com (Alejandro E Murillo) Date: Mon, 03 Mar 2014 19:29:13 -0700 Subject: jdk8-b132: HotSpot Message-ID: <53153A79.3060102@oracle.com> hs25-b70 has been integrated into jdk8-b132. http://hg.openjdk.java.net/jdk8/jdk8/rev/2a8f4c022aa0 http://hg.openjdk.java.net/jdk8/jdk8/corba/rev/84fed37bbe64 http://hg.openjdk.java.net/jdk8/jdk8/hotspot/rev/0c94c41dcd70 http://hg.openjdk.java.net/jdk8/jdk8/jaxp/rev/5993346020d1 http://hg.openjdk.java.net/jdk8/jdk8/jaxws/rev/c2be0dd15dbf http://hg.openjdk.java.net/jdk8/jdk8/jdk/rev/43cb25339b55 http://hg.openjdk.java.net/jdk8/jdk8/langtools/rev/c8a87a58eb3e http://hg.openjdk.java.net/jdk8/jdk8/nashorn/rev/5dbdae28a6f3 hs25-b70 contains only one new change: 8036100: Default method returns true for a while, and then returns false PIT has been waived -- Alejandro From david.katleman at oracle.com Tue Mar 4 12:00:16 2014 From: david.katleman at oracle.com (david.katleman at oracle.com) Date: Tue, 04 Mar 2014 20:00:16 +0000 Subject: hg: jdk8/jdk8: Added tag jdk8-b132 for changeset 2a8f4c022aa0 Message-ID: <20140304200016.AB71D624BF@hg.openjdk.java.net> Changeset: 1773f1fd0fac Author: katleman Date: 2014-03-04 11:50 -0800 URL: http://hg.openjdk.java.net/jdk8/jdk8/rev/1773f1fd0fac Added tag jdk8-b132 for changeset 2a8f4c022aa0 ! .hgtags From david.katleman at oracle.com Tue Mar 4 12:00:24 2014 From: david.katleman at oracle.com (david.katleman at oracle.com) Date: Tue, 04 Mar 2014 20:00:24 +0000 Subject: hg: jdk8/jdk8/corba: Added tag jdk8-b132 for changeset 84fed37bbe64 Message-ID: <20140304200025.52F30624C0@hg.openjdk.java.net> Changeset: 3d96f0a5f9e2 Author: katleman Date: 2014-03-04 11:50 -0800 URL: http://hg.openjdk.java.net/jdk8/jdk8/corba/rev/3d96f0a5f9e2 Added tag jdk8-b132 for changeset 84fed37bbe64 ! .hgtags From david.katleman at oracle.com Tue Mar 4 12:01:24 2014 From: david.katleman at oracle.com (david.katleman at oracle.com) Date: Tue, 04 Mar 2014 20:01:24 +0000 Subject: hg: jdk8/jdk8/hotspot: Added tag jdk8-b132 for changeset 0c94c41dcd70 Message-ID: <20140304200126.DFC93624C1@hg.openjdk.java.net> Changeset: 87ee5ee27509 Author: katleman Date: 2014-03-04 11:51 -0800 URL: http://hg.openjdk.java.net/jdk8/jdk8/hotspot/rev/87ee5ee27509 Added tag jdk8-b132 for changeset 0c94c41dcd70 ! .hgtags From david.katleman at oracle.com Tue Mar 4 12:05:22 2014 From: david.katleman at oracle.com (david.katleman at oracle.com) Date: Tue, 04 Mar 2014 20:05:22 +0000 Subject: hg: jdk8/jdk8/jaxp: Added tag jdk8-b132 for changeset 5993346020d1 Message-ID: <20140304200524.886C1624C2@hg.openjdk.java.net> Changeset: 0c49f9209035 Author: katleman Date: 2014-03-04 11:51 -0800 URL: http://hg.openjdk.java.net/jdk8/jdk8/jaxp/rev/0c49f9209035 Added tag jdk8-b132 for changeset 5993346020d1 ! .hgtags From david.katleman at oracle.com Tue Mar 4 12:05:35 2014 From: david.katleman at oracle.com (david.katleman at oracle.com) Date: Tue, 04 Mar 2014 20:05:35 +0000 Subject: hg: jdk8/jdk8/jaxws: Added tag jdk8-b132 for changeset c2be0dd15dbf Message-ID: <20140304200537.C2926624C3@hg.openjdk.java.net> Changeset: d03dd22762db Author: katleman Date: 2014-03-04 11:51 -0800 URL: http://hg.openjdk.java.net/jdk8/jdk8/jaxws/rev/d03dd22762db Added tag jdk8-b132 for changeset c2be0dd15dbf ! .hgtags From david.katleman at oracle.com Tue Mar 4 12:05:54 2014 From: david.katleman at oracle.com (david.katleman at oracle.com) Date: Tue, 04 Mar 2014 20:05:54 +0000 Subject: hg: jdk8/jdk8/jdk: Added tag jdk8-b132 for changeset 43cb25339b55 Message-ID: <20140304200608.81B64624C4@hg.openjdk.java.net> Changeset: 687fd7c7986d Author: katleman Date: 2014-03-04 11:51 -0800 URL: http://hg.openjdk.java.net/jdk8/jdk8/jdk/rev/687fd7c7986d Added tag jdk8-b132 for changeset 43cb25339b55 ! .hgtags From david.katleman at oracle.com Tue Mar 4 12:11:39 2014 From: david.katleman at oracle.com (david.katleman at oracle.com) Date: Tue, 04 Mar 2014 20:11:39 +0000 Subject: hg: jdk8/jdk8/langtools: Added tag jdk8-b132 for changeset c8a87a58eb3e Message-ID: <20140304201143.056E0624C5@hg.openjdk.java.net> Changeset: 1ff9d5118aae Author: katleman Date: 2014-03-04 11:52 -0800 URL: http://hg.openjdk.java.net/jdk8/jdk8/langtools/rev/1ff9d5118aae Added tag jdk8-b132 for changeset c8a87a58eb3e ! .hgtags From david.katleman at oracle.com Tue Mar 4 12:11:54 2014 From: david.katleman at oracle.com (david.katleman at oracle.com) Date: Tue, 04 Mar 2014 20:11:54 +0000 Subject: hg: jdk8/jdk8/nashorn: Added tag jdk8-b132 for changeset 5dbdae28a6f3 Message-ID: <20140304201155.AF928624C6@hg.openjdk.java.net> Changeset: 096dc407d310 Author: katleman Date: 2014-03-04 11:52 -0800 URL: http://hg.openjdk.java.net/jdk8/jdk8/nashorn/rev/096dc407d310 Added tag jdk8-b132 for changeset 5dbdae28a6f3 ! .hgtags From mark.reinhold at oracle.com Thu Mar 6 09:33:04 2014 From: mark.reinhold at oracle.com (mark.reinhold at oracle.com) Date: Thu, 06 Mar 2014 09:33:04 -0800 Subject: JDK 8: Third Release Candidate Message-ID: <20140306093304.675506@eggemoggin.niobe.net> Last week a critical correctness bug in HotSpot's handling of default methods was reported [1], and prior to that we found a JCK failure in CORBA [2]. We've fixed both bugs in the third JDK 8 Release Candidate, build 132. Binaries available here, as usual: https://jdk8.java.net/download.html - Mark [1] https://bugs.openjdk.java.net/browse/JDK-8036558 [2] https://bugs.openjdk.java.net/browse/JDK-8035618 From radu.murzea at gmail.com Thu Mar 6 12:59:57 2014 From: radu.murzea at gmail.com (Radu Murzea) Date: Thu, 06 Mar 2014 22:59:57 +0200 Subject: Is GA date still solid ? In-Reply-To: References: Message-ID: <5318E1CD.20605@gmail.com> Is the GA release date in danger because of this ? Or is it still set in stone for 18th March ? On 3/6/2014 10:00 PM, jdk8-dev-request at openjdk.java.net wrote: > Date: Thu, 06 Mar 2014 09:33:04 -0800 > From: mark.reinhold at oracle.com > Subject: JDK 8: Third Release Candidate > To: jdk8-dev at openjdk.java.net > Message-ID: <20140306093304.675506 at eggemoggin.niobe.net> > Content-Type: text/plain; charset=us-ascii > > Last week a critical correctness bug in HotSpot's handling of default > methods was reported [1], and prior to that we found a JCK failure in > CORBA [2]. We've fixed both bugs in the third JDK 8 Release Candidate, > build 132. > > Binaries available here, as usual: https://jdk8.java.net/download.html > > - Mark > > > [1] https://bugs.openjdk.java.net/browse/JDK-8036558 > [2] https://bugs.openjdk.java.net/browse/JDK-8035618 From mark.reinhold at oracle.com Thu Mar 6 13:26:00 2014 From: mark.reinhold at oracle.com (mark.reinhold at oracle.com) Date: Thu, 06 Mar 2014 13:26:00 -0800 Subject: Is GA date still solid ? In-Reply-To: <5318E1CD.20605@gmail.com> References: , <5318E1CD.20605@gmail.com> Message-ID: <20140306132600.426745@eggemoggin.niobe.net> 2014/3/6 4:59 -0800, radu.murzea at gmail.com: > Is the GA release date in danger because of this ? Or is it still set in > stone for 18th March ? We are still aiming for 18 March. - Mark From pavel.bucek at oracle.com Wed Mar 12 18:12:24 2014 From: pavel.bucek at oracle.com (Pavel Bucek) Date: Wed, 12 Mar 2014 19:12:24 +0100 Subject: JDK 8 - Lambda - Reflection issues Message-ID: <5320A388.9030000@oracle.com> Hello all, I have an issue with getting generic parameter when using lambdas. I can get the type when using anonymous classes. code sample will be more descriptive than anything I would say, so.. : public class Main { public static interface A { public void method(T param); } public static void main(String[] args) { final A
anonClass = new A
() { @Override public void method(Main param) { System.out.println("234"); } }; final A
lambda = param -> System.out.println("234"); //following does not help. // final A
lambda = (A
)param -> System.out.println("234"); // output: Main.Main$A
System.out.println("$ " + anonClass.getClass().getGenericInterfaces()[0]); // output: interface Main$A ### generic type info is already lost (no
) System.out.println("# " + lambda.getClass().getGenericInterfaces()[0]); // parameterized type from annon class final Type t = ((ParameterizedType)anonClass.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0]; System.out.println("$ " + t); // parameterized type from lambda System.out.println("# " + "???"); } } I was not able to find any useful documentation or article about this, so sorry if this is something common - feel free to RTM me (with relevant link please). Thanks and regards, Pavel From forax at univ-mlv.fr Wed Mar 12 18:42:06 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 12 Mar 2014 19:42:06 +0100 Subject: JDK 8 - Lambda - Reflection issues In-Reply-To: <5320A388.9030000@oracle.com> References: <5320A388.9030000@oracle.com> Message-ID: <5320AA7E.7060507@univ-mlv.fr> On 03/12/2014 07:12 PM, Pavel Bucek wrote: > Hello all, > > I have an issue with getting generic parameter when using lambdas. I > can get the type when using anonymous classes. > > code sample will be more descriptive than anything I would say, so.. : > > public class Main { > > public static interface A { > public void method(T param); > } > > public static void main(String[] args) { > > final A
anonClass = new A
() { > @Override > public void method(Main param) { > System.out.println("234"); > } > }; > > final A
lambda = param -> System.out.println("234"); > > //following does not help. > // final A
lambda = (A
)param -> > System.out.println("234"); > > > // output: Main.Main$A
> System.out.println("$ " + > anonClass.getClass().getGenericInterfaces()[0]); > > // output: interface Main$A ### generic type info is > already lost (no
) > System.out.println("# " + > lambda.getClass().getGenericInterfaces()[0]); > > // parameterized type from annon class > final Type t = > ((ParameterizedType)anonClass.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0]; > System.out.println("$ " + t); > > // parameterized type from lambda > System.out.println("# " + "???"); > } > } > > I was not able to find any useful documentation or article about this, > so sorry if this is something common - feel free to RTM me (with > relevant link please). > > Thanks and regards, > Pavel As you have seen a lambda is not an anonymous class :) A non-serializable lambda is more lightweight than an anonymous class so the generic information that are transmitted from the bytecode to the runtime (the lambda metafactory) are not kept inside the lambda class (a lambda class may be shared by several different lambdas). A serializable lambda keep these information because you need them to deserialize a lambda but they are not publicly available The current implementation encoded them in the bytecode and this bytecode is not publicly available so unless you serialize the lambda and serialize it by hand, you can not have access to these information. So you can not use a lambda with frameworks like Jackson that use the TypeReference idiom, you can still use an anonymous class for that :) cheers, R?mi From pavel.bucek at oracle.com Thu Mar 13 08:56:26 2014 From: pavel.bucek at oracle.com (Pavel Bucek) Date: Thu, 13 Mar 2014 09:56:26 +0100 Subject: JDK 8 - Lambda - Reflection issues In-Reply-To: <5320AA7E.7060507@univ-mlv.fr> References: <5320A388.9030000@oracle.com> <5320AA7E.7060507@univ-mlv.fr> Message-ID: <532172BA.3070303@oracle.com> Hi Remi, thanks! I suspected that it would not be possible, but it is always better to have the confirmation. My context is slightly different, but the consequences are similar like with the jackson library. Seems a little unfortunate to have the possibility to use lambdas even on places where it cannot work - my guess is that this will become one of most frequent question on some mailing lists.. (you don't really need to read further) I'm working on JSR 356 - Java API for WebSocket implementation and there is an interface: interface MessageHandler.Whole extends MessageHandler { void onMessage(T message); } And then there is a Session object, which has method "void addMessageHandler(MessageHandler handler);". Obvious common use of this method is: session.addMessageHandler(new MessageHandler.Whole() { @Override public void onMessage(String message) { // ... } }); I can see my IDE automatically offers me to transform this to lambda expression (this is actually what worries me a little, because all users will see that and do it - because why not - it seems to be equivalent with anonymous class). When this suggestion is accepted, previous statement is transformed into: session.addMessageHandler((MessageHandler.Whole) message -> { // ... }); which looks prettier, but just does not work and cannot work :/ I guess we could provide wrapper class, something like: public static class WholeMessageHandler implements MessageHandler.Whole { private final Class genericParam; private final MessageHandler.Whole wholeMessageHandler; protected WholeMessageHandler(Class genericParam, MessageHandler.Whole wholeMessageHandler) { this.genericParam = genericParam; this.wholeMessageHandler = wholeMessageHandler; } public Class getGenericParam() { return genericParam; } @Override public void onMessage(T message) { wholeMessageHandler.onMessage(message); } } and then, when user would want to use lambdas, do it with help of that class: session.addMessageHandler(new WholeMessageHandler
(Main.class, param -> System.out.println("234"))); so I can do this like a workaround, but anyway, the initial recommendation of the IDE is bad enough to cause us lots of mailing list traffic and explanations why is not possible to use lambda in "native" fashion. Anyway - I'm not describing my pain just to share my pain - if anyone have any suggestions how this can be solved, I'm all ears; any reply would be greatly appreciated. Thanks! Pavel On 12/03/14 19:42, Remi Forax wrote: > On 03/12/2014 07:12 PM, Pavel Bucek wrote: >> Hello all, >> >> I have an issue with getting generic parameter when using lambdas. I >> can get the type when using anonymous classes. >> >> code sample will be more descriptive than anything I would say, so.. : >> >> public class Main { >> >> public static interface A { >> public void method(T param); >> } >> >> public static void main(String[] args) { >> >> final A
anonClass = new A
() { >> @Override >> public void method(Main param) { >> System.out.println("234"); >> } >> }; >> >> final A
lambda = param -> System.out.println("234"); >> >> //following does not help. >> // final A
lambda = (A
)param -> >> System.out.println("234"); >> >> >> // output: Main.Main$A
>> System.out.println("$ " + >> anonClass.getClass().getGenericInterfaces()[0]); >> >> // output: interface Main$A ### generic type info is >> already lost (no
) >> System.out.println("# " + >> lambda.getClass().getGenericInterfaces()[0]); >> >> // parameterized type from annon class >> final Type t = >> ((ParameterizedType)anonClass.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0]; >> System.out.println("$ " + t); >> >> // parameterized type from lambda >> System.out.println("# " + "???"); >> } >> } >> >> I was not able to find any useful documentation or article about >> this, so sorry if this is something common - feel free to RTM me >> (with relevant link please). >> >> Thanks and regards, >> Pavel > > As you have seen a lambda is not an anonymous class :) > > A non-serializable lambda is more lightweight than an anonymous class > so the generic information that are transmitted from the bytecode to > the runtime (the lambda metafactory) are not kept inside the lambda > class (a lambda class may be shared by several different lambdas). > > A serializable lambda keep these information because you need them to > deserialize a lambda but they are not publicly available > The current implementation encoded them in the bytecode and this > bytecode is not publicly available so unless you serialize the lambda > and serialize it by hand, you can not have access to these information. > > So you can not use a lambda with frameworks like Jackson that use the > TypeReference idiom, > you can still use an anonymous class for that :) > > cheers, > R?mi > > > From pavel.bucek at oracle.com Thu Mar 13 09:10:46 2014 From: pavel.bucek at oracle.com (Pavel Bucek) Date: Thu, 13 Mar 2014 10:10:46 +0100 Subject: JDK 8 - Lambda - Reflection issues In-Reply-To: <532172BA.3070303@oracle.com> References: <5320A388.9030000@oracle.com> <5320AA7E.7060507@univ-mlv.fr> <532172BA.3070303@oracle.com> Message-ID: <53217616.2010401@oracle.com> just for the sake of correctness - WholeMessageHandler does not need to have Class genericParam field and constructor param - anonymous class which just wraps the lambda expression is good enough. On 13/03/14 09:56, Pavel Bucek wrote: > Hi Remi, > > thanks! I suspected that it would not be possible, but it is always > better to have the confirmation. > > My context is slightly different, but the consequences are similar > like with the jackson library. Seems a little unfortunate to have the > possibility to use lambdas even on places where it cannot work - my > guess is that this will become one of most frequent question on some > mailing lists.. > > (you don't really need to read further) > > I'm working on JSR 356 - Java API for WebSocket implementation and > there is an interface: > > interface MessageHandler.Whole extends MessageHandler { > void onMessage(T message); > } > > And then there is a Session object, which has method "void > addMessageHandler(MessageHandler handler);". Obvious common use of > this method is: > > session.addMessageHandler(new MessageHandler.Whole() { > @Override > public void onMessage(String message) { > // ... > } > }); > > I can see my IDE automatically offers me to transform this to lambda > expression (this is actually what worries me a little, because all > users will see that and do it - because why not - it seems to be > equivalent with anonymous class). When this suggestion is accepted, > previous statement is transformed into: > > session.addMessageHandler((MessageHandler.Whole) message -> { > // ... > }); > > which looks prettier, but just does not work and cannot work :/ I > guess we could provide wrapper class, something like: > > public static class WholeMessageHandler implements > MessageHandler.Whole { > > private final Class genericParam; > private final MessageHandler.Whole wholeMessageHandler; > > protected WholeMessageHandler(Class genericParam, > MessageHandler.Whole wholeMessageHandler) { > this.genericParam = genericParam; > this.wholeMessageHandler = wholeMessageHandler; > } > > public Class getGenericParam() { > return genericParam; > } > > @Override > public void onMessage(T message) { > wholeMessageHandler.onMessage(message); > } > } > > and then, when user would want to use lambdas, do it with help of that > class: > > session.addMessageHandler(new WholeMessageHandler
(Main.class, > param -> System.out.println("234"))); > > so I can do this like a workaround, but anyway, the initial > recommendation of the IDE is bad enough to cause us lots of mailing > list traffic and explanations why is not possible to use lambda in > "native" fashion. Anyway - I'm not describing my pain just to share my > pain - if anyone have any suggestions how this can be solved, I'm all > ears; any reply would be greatly appreciated. > > Thanks! > Pavel > > > On 12/03/14 19:42, Remi Forax wrote: >> On 03/12/2014 07:12 PM, Pavel Bucek wrote: >>> Hello all, >>> >>> I have an issue with getting generic parameter when using lambdas. I >>> can get the type when using anonymous classes. >>> >>> code sample will be more descriptive than anything I would say, so.. : >>> >>> public class Main { >>> >>> public static interface A { >>> public void method(T param); >>> } >>> >>> public static void main(String[] args) { >>> >>> final A
anonClass = new A
() { >>> @Override >>> public void method(Main param) { >>> System.out.println("234"); >>> } >>> }; >>> >>> final A
lambda = param -> System.out.println("234"); >>> >>> //following does not help. >>> // final A
lambda = (A
)param -> >>> System.out.println("234"); >>> >>> >>> // output: Main.Main$A
>>> System.out.println("$ " + >>> anonClass.getClass().getGenericInterfaces()[0]); >>> >>> // output: interface Main$A ### generic type info >>> is already lost (no
) >>> System.out.println("# " + >>> lambda.getClass().getGenericInterfaces()[0]); >>> >>> // parameterized type from annon class >>> final Type t = >>> ((ParameterizedType)anonClass.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0]; >>> System.out.println("$ " + t); >>> >>> // parameterized type from lambda >>> System.out.println("# " + "???"); >>> } >>> } >>> >>> I was not able to find any useful documentation or article about >>> this, so sorry if this is something common - feel free to RTM me >>> (with relevant link please). >>> >>> Thanks and regards, >>> Pavel >> >> As you have seen a lambda is not an anonymous class :) >> >> A non-serializable lambda is more lightweight than an anonymous class >> so the generic information that are transmitted from the bytecode to >> the runtime (the lambda metafactory) are not kept inside the lambda >> class (a lambda class may be shared by several different lambdas). >> >> A serializable lambda keep these information because you need them to >> deserialize a lambda but they are not publicly available >> The current implementation encoded them in the bytecode and this >> bytecode is not publicly available so unless you serialize the lambda >> and serialize it by hand, you can not have access to these information. >> >> So you can not use a lambda with frameworks like Jackson that use the >> TypeReference idiom, >> you can still use an anonymous class for that :) >> >> cheers, >> R?mi >> >> >> > > > From paul.sandoz at oracle.com Thu Mar 13 10:09:52 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 13 Mar 2014 11:09:52 +0100 Subject: JDK 8 - Lambda - Reflection issues In-Reply-To: <5320AA7E.7060507@univ-mlv.fr> References: <5320A388.9030000@oracle.com> <5320AA7E.7060507@univ-mlv.fr> Message-ID: <56F11268-0F9D-4FF4-B609-0212CC15CE46@oracle.com> On Mar 12, 2014, at 7:42 PM, Remi Forax wrote: > > As you have seen a lambda is not an anonymous class :) > > A non-serializable lambda is more lightweight than an anonymous class so the generic information that are transmitted from the bytecode to the runtime (the lambda metafactory) are not kept inside the lambda class (a lambda class may be shared by several different lambdas). > Seems like the reflection API is at the wrong level and a Java model/mirror API might be able to handle this correctly? Paul. From pavel.bucek at oracle.com Fri Mar 14 16:43:09 2014 From: pavel.bucek at oracle.com (Pavel Bucek) Date: Fri, 14 Mar 2014 17:43:09 +0100 Subject: JDK 8 - Lambda - Reflection issues In-Reply-To: <53217616.2010401@oracle.com> References: <5320A388.9030000@oracle.com> <5320AA7E.7060507@univ-mlv.fr> <532172BA.3070303@oracle.com> <53217616.2010401@oracle.com> Message-ID: <5323319D.4090101@oracle.com> I'm considering filing this as a backward compatibility issue against JDK 8 - my reasoning would be that I should be able to still get the same information from the reflection API as I did in previous versions of JDK and I don't have a way how to restrict lambda usage in the already designed and published API. Can anyone give me any reason why shouldn't I do that? (I suspect something like "read [this][link] document, where we explicitly say that this is to be expected thus the issue is invalid". Thanks! Pavel On 13/03/14 10:10, Pavel Bucek wrote: > just for the sake of correctness - WholeMessageHandler does not > need to have Class genericParam field and constructor param - > anonymous class which just wraps the lambda expression is good enough. > > On 13/03/14 09:56, Pavel Bucek wrote: >> Hi Remi, >> >> thanks! I suspected that it would not be possible, but it is always >> better to have the confirmation. >> >> My context is slightly different, but the consequences are similar >> like with the jackson library. Seems a little unfortunate to have the >> possibility to use lambdas even on places where it cannot work - my >> guess is that this will become one of most frequent question on some >> mailing lists.. >> >> (you don't really need to read further) >> >> I'm working on JSR 356 - Java API for WebSocket implementation and >> there is an interface: >> >> interface MessageHandler.Whole extends MessageHandler { >> void onMessage(T message); >> } >> >> And then there is a Session object, which has method "void >> addMessageHandler(MessageHandler handler);". Obvious common use of >> this method is: >> >> session.addMessageHandler(new MessageHandler.Whole() { >> @Override >> public void onMessage(String message) { >> // ... >> } >> }); >> >> I can see my IDE automatically offers me to transform this to lambda >> expression (this is actually what worries me a little, because all >> users will see that and do it - because why not - it seems to be >> equivalent with anonymous class). When this suggestion is accepted, >> previous statement is transformed into: >> >> session.addMessageHandler((MessageHandler.Whole) message -> { >> // ... >> }); >> >> which looks prettier, but just does not work and cannot work :/ I >> guess we could provide wrapper class, something like: >> >> public static class WholeMessageHandler implements >> MessageHandler.Whole { >> >> private final Class genericParam; >> private final MessageHandler.Whole wholeMessageHandler; >> >> protected WholeMessageHandler(Class genericParam, >> MessageHandler.Whole wholeMessageHandler) { >> this.genericParam = genericParam; >> this.wholeMessageHandler = wholeMessageHandler; >> } >> >> public Class getGenericParam() { >> return genericParam; >> } >> >> @Override >> public void onMessage(T message) { >> wholeMessageHandler.onMessage(message); >> } >> } >> >> and then, when user would want to use lambdas, do it with help of >> that class: >> >> session.addMessageHandler(new WholeMessageHandler
(Main.class, >> param -> System.out.println("234"))); >> >> so I can do this like a workaround, but anyway, the initial >> recommendation of the IDE is bad enough to cause us lots of mailing >> list traffic and explanations why is not possible to use lambda in >> "native" fashion. Anyway - I'm not describing my pain just to share >> my pain - if anyone have any suggestions how this can be solved, I'm >> all ears; any reply would be greatly appreciated. >> >> Thanks! >> Pavel >> >> >> On 12/03/14 19:42, Remi Forax wrote: >>> On 03/12/2014 07:12 PM, Pavel Bucek wrote: >>>> Hello all, >>>> >>>> I have an issue with getting generic parameter when using lambdas. >>>> I can get the type when using anonymous classes. >>>> >>>> code sample will be more descriptive than anything I would say, so.. : >>>> >>>> public class Main { >>>> >>>> public static interface A { >>>> public void method(T param); >>>> } >>>> >>>> public static void main(String[] args) { >>>> >>>> final A
anonClass = new A
() { >>>> @Override >>>> public void method(Main param) { >>>> System.out.println("234"); >>>> } >>>> }; >>>> >>>> final A
lambda = param -> System.out.println("234"); >>>> >>>> //following does not help. >>>> // final A
lambda = (A
)param -> >>>> System.out.println("234"); >>>> >>>> >>>> // output: Main.Main$A
>>>> System.out.println("$ " + >>>> anonClass.getClass().getGenericInterfaces()[0]); >>>> >>>> // output: interface Main$A ### generic type info >>>> is already lost (no
) >>>> System.out.println("# " + >>>> lambda.getClass().getGenericInterfaces()[0]); >>>> >>>> // parameterized type from annon class >>>> final Type t = >>>> ((ParameterizedType)anonClass.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0]; >>>> System.out.println("$ " + t); >>>> >>>> // parameterized type from lambda >>>> System.out.println("# " + "???"); >>>> } >>>> } >>>> >>>> I was not able to find any useful documentation or article about >>>> this, so sorry if this is something common - feel free to RTM me >>>> (with relevant link please). >>>> >>>> Thanks and regards, >>>> Pavel >>> >>> As you have seen a lambda is not an anonymous class :) >>> >>> A non-serializable lambda is more lightweight than an anonymous >>> class so the generic information that are transmitted from the >>> bytecode to the runtime (the lambda metafactory) are not kept inside >>> the lambda class (a lambda class may be shared by several different >>> lambdas). >>> >>> A serializable lambda keep these information because you need them >>> to deserialize a lambda but they are not publicly available >>> The current implementation encoded them in the bytecode and this >>> bytecode is not publicly available so unless you serialize the >>> lambda and serialize it by hand, you can not have access to these >>> information. >>> >>> So you can not use a lambda with frameworks like Jackson that use >>> the TypeReference idiom, >>> you can still use an anonymous class for that :) >>> >>> cheers, >>> R?mi >>> >>> >>> >> >> >> > > > From forax at univ-mlv.fr Fri Mar 14 18:14:14 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Fri, 14 Mar 2014 19:14:14 +0100 Subject: JDK 8 - Lambda - Reflection issues In-Reply-To: <532172BA.3070303@oracle.com> References: <5320A388.9030000@oracle.com> <5320AA7E.7060507@univ-mlv.fr> <532172BA.3070303@oracle.com> Message-ID: <532346F6.2040800@univ-mlv.fr> On 03/13/2014 09:56 AM, Pavel Bucek wrote: > Hi Remi, > > thanks! I suspected that it would not be possible, but it is always > better to have the confirmation. > > My context is slightly different, but the consequences are similar > like with the jackson library. Seems a little unfortunate to have the > possibility to use lambdas even on places where it cannot work - my > guess is that this will become one of most frequent question on some > mailing lists.. > > (you don't really need to read further) > > I'm working on JSR 356 - Java API for WebSocket implementation and > there is an interface: > > interface MessageHandler.Whole extends MessageHandler { > void onMessage(T message); > } > > And then there is a Session object, which has method "void > addMessageHandler(MessageHandler handler);". Obvious common use of > this method is: > > session.addMessageHandler(new MessageHandler.Whole() { > @Override > public void onMessage(String message) { > // ... > } > }); > > I can see my IDE automatically offers me to transform this to lambda > expression (this is actually what worries me a little, because all > users will see that and do it - because why not - it seems to be > equivalent with anonymous class). When this suggestion is accepted, > previous statement is transformed into: > > session.addMessageHandler((MessageHandler.Whole) message -> { > // ... > }); > > which looks prettier, but just does not work and cannot work :/ I > guess we could provide wrapper class, something like: > > public static class WholeMessageHandler implements > MessageHandler.Whole { > > private final Class genericParam; > private final MessageHandler.Whole wholeMessageHandler; > > protected WholeMessageHandler(Class genericParam, > MessageHandler.Whole wholeMessageHandler) { > this.genericParam = genericParam; > this.wholeMessageHandler = wholeMessageHandler; > } > > public Class getGenericParam() { > return genericParam; > } > > @Override > public void onMessage(T message) { > wholeMessageHandler.onMessage(message); > } > } > > and then, when user would want to use lambdas, do it with help of that > class: > > session.addMessageHandler(new WholeMessageHandler
(Main.class, > param -> System.out.println("234"))); > > so I can do this like a workaround, but anyway, the initial > recommendation of the IDE is bad enough to cause us lots of mailing > list traffic and explanations why is not possible to use lambda in > "native" fashion. Anyway - I'm not describing my pain just to share my > pain - if anyone have any suggestions how this can be solved, I'm all > ears; any reply would be greatly appreciated. > > Thanks! > Pavel I should have written a blog post on that subject a long time ago, doing runtime inspection of type information used by javac in a library is usually harmful, here is why. 1) Java is not the only language on the JVM, the other compiler/runtime doesn't necessarily have type information, by requiring type information you consider groovy, nashorn, jruby, etc guys as second citizens. 2) The code that does the introspection is hard to get right, a simple example that shows that you have to do type propagation: interface Foo extends MessageHandler.Whole { } class Bar extends Comparable, Foo { ... } session.addMessageHandler(new Bar()); 3) At runtime, it can be very slow because it may have to crawle all the super types, and look for a fix point when you have types that have recursive bounds (like enums or comparable) 4) Let suppose the introspection code found a type, then it usually relies on an implicit configuration to find how to convert the value (usually a String) to the type. Implicit configuration == nigthmare when testing if the configuration used by the user code is not the default one So instead of using a broken idiom, I think it's better to explicitly specify the conversion using either a lambda or better a method reference as first parameter. session.addMessageHandler(Integer:parseInt, integer -> ...); session.addMessageHandler(Paths::get, path -> ...); cheers, R?mi > > > On 12/03/14 19:42, Remi Forax wrote: >> On 03/12/2014 07:12 PM, Pavel Bucek wrote: >>> Hello all, >>> >>> I have an issue with getting generic parameter when using lambdas. I >>> can get the type when using anonymous classes. >>> >>> code sample will be more descriptive than anything I would say, so.. : >>> >>> public class Main { >>> >>> public static interface A { >>> public void method(T param); >>> } >>> >>> public static void main(String[] args) { >>> >>> final A
anonClass = new A
() { >>> @Override >>> public void method(Main param) { >>> System.out.println("234"); >>> } >>> }; >>> >>> final A
lambda = param -> System.out.println("234"); >>> >>> //following does not help. >>> // final A
lambda = (A
)param -> >>> System.out.println("234"); >>> >>> >>> // output: Main.Main$A
>>> System.out.println("$ " + >>> anonClass.getClass().getGenericInterfaces()[0]); >>> >>> // output: interface Main$A ### generic type info >>> is already lost (no
) >>> System.out.println("# " + >>> lambda.getClass().getGenericInterfaces()[0]); >>> >>> // parameterized type from annon class >>> final Type t = >>> ((ParameterizedType)anonClass.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0]; >>> System.out.println("$ " + t); >>> >>> // parameterized type from lambda >>> System.out.println("# " + "???"); >>> } >>> } >>> >>> I was not able to find any useful documentation or article about >>> this, so sorry if this is something common - feel free to RTM me >>> (with relevant link please). >>> >>> Thanks and regards, >>> Pavel >> >> As you have seen a lambda is not an anonymous class :) >> >> A non-serializable lambda is more lightweight than an anonymous class >> so the generic information that are transmitted from the bytecode to >> the runtime (the lambda metafactory) are not kept inside the lambda >> class (a lambda class may be shared by several different lambdas). >> >> A serializable lambda keep these information because you need them to >> deserialize a lambda but they are not publicly available >> The current implementation encoded them in the bytecode and this >> bytecode is not publicly available so unless you serialize the lambda >> and serialize it by hand, you can not have access to these information. >> >> So you can not use a lambda with frameworks like Jackson that use the >> TypeReference idiom, >> you can still use an anonymous class for that :) >> >> cheers, >> R?mi >> >> >> > From forax at univ-mlv.fr Fri Mar 14 18:23:08 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Fri, 14 Mar 2014 19:23:08 +0100 Subject: JDK 8 - Lambda - Reflection issues In-Reply-To: <56F11268-0F9D-4FF4-B609-0212CC15CE46@oracle.com> References: <5320A388.9030000@oracle.com> <5320AA7E.7060507@univ-mlv.fr> <56F11268-0F9D-4FF4-B609-0212CC15CE46@oracle.com> Message-ID: <5323490C.3080500@univ-mlv.fr> On 03/13/2014 11:09 AM, Paul Sandoz wrote: > On Mar 12, 2014, at 7:42 PM, Remi Forax wrote: >> As you have seen a lambda is not an anonymous class :) >> >> A non-serializable lambda is more lightweight than an anonymous class so the generic information that are transmitted from the bytecode to the runtime (the lambda metafactory) are not kept inside the lambda class (a lambda class may be shared by several different lambdas). >> > Seems like the reflection API is at the wrong level and a Java model/mirror API might be able to handle this correctly? yes, it's a hack, using a declared type (type are artifact of the compiler) at runtime (in the VM realm) to convert a message is not very natural. yes, it's possible to use an annotation processor for that, it's a far better that trying to emulate the compiler job at runtime. Now, requiring an annotation processor make the API heavier to use. > > Paul. > cheers, R?mi From forax at univ-mlv.fr Fri Mar 14 18:26:40 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Fri, 14 Mar 2014 19:26:40 +0100 Subject: JDK 8 - Lambda - Reflection issues In-Reply-To: <5323319D.4090101@oracle.com> References: <5320A388.9030000@oracle.com> <5320AA7E.7060507@univ-mlv.fr> <532172BA.3070303@oracle.com> <53217616.2010401@oracle.com> <5323319D.4090101@oracle.com> Message-ID: <532349E0.6080904@univ-mlv.fr> On 03/14/2014 05:43 PM, Pavel Bucek wrote: > I'm considering filing this as a backward compatibility issue against > JDK 8 - my reasoning would be that I should be able to still get the > same information from the reflection API as I did in previous versions > of JDK and I don't have a way how to restrict lambda usage in the > already designed and published API. > > Can anyone give me any reason why shouldn't I do that? (I suspect > something like "read [this][link] document, where we explicitly say > that this is to be expected thus the issue is invalid". > > Thanks! > Pavel You should do submit a bug, so we will document for everyone why this issue is invalid :) cheers, R?mi > > On 13/03/14 10:10, Pavel Bucek wrote: >> just for the sake of correctness - WholeMessageHandler does not >> need to have Class genericParam field and constructor param - >> anonymous class which just wraps the lambda expression is good enough. >> >> On 13/03/14 09:56, Pavel Bucek wrote: >>> Hi Remi, >>> >>> thanks! I suspected that it would not be possible, but it is always >>> better to have the confirmation. >>> >>> My context is slightly different, but the consequences are similar >>> like with the jackson library. Seems a little unfortunate to have >>> the possibility to use lambdas even on places where it cannot work - >>> my guess is that this will become one of most frequent question on >>> some mailing lists.. >>> >>> (you don't really need to read further) >>> >>> I'm working on JSR 356 - Java API for WebSocket implementation and >>> there is an interface: >>> >>> interface MessageHandler.Whole extends MessageHandler { >>> void onMessage(T message); >>> } >>> >>> And then there is a Session object, which has method "void >>> addMessageHandler(MessageHandler handler);". Obvious common use of >>> this method is: >>> >>> session.addMessageHandler(new MessageHandler.Whole() { >>> @Override >>> public void onMessage(String message) { >>> // ... >>> } >>> }); >>> >>> I can see my IDE automatically offers me to transform this to lambda >>> expression (this is actually what worries me a little, because all >>> users will see that and do it - because why not - it seems to be >>> equivalent with anonymous class). When this suggestion is accepted, >>> previous statement is transformed into: >>> >>> session.addMessageHandler((MessageHandler.Whole) message -> { >>> // ... >>> }); >>> >>> which looks prettier, but just does not work and cannot work :/ I >>> guess we could provide wrapper class, something like: >>> >>> public static class WholeMessageHandler implements >>> MessageHandler.Whole { >>> >>> private final Class genericParam; >>> private final MessageHandler.Whole wholeMessageHandler; >>> >>> protected WholeMessageHandler(Class genericParam, >>> MessageHandler.Whole wholeMessageHandler) { >>> this.genericParam = genericParam; >>> this.wholeMessageHandler = wholeMessageHandler; >>> } >>> >>> public Class getGenericParam() { >>> return genericParam; >>> } >>> >>> @Override >>> public void onMessage(T message) { >>> wholeMessageHandler.onMessage(message); >>> } >>> } >>> >>> and then, when user would want to use lambdas, do it with help of >>> that class: >>> >>> session.addMessageHandler(new WholeMessageHandler
(Main.class, >>> param -> System.out.println("234"))); >>> >>> so I can do this like a workaround, but anyway, the initial >>> recommendation of the IDE is bad enough to cause us lots of mailing >>> list traffic and explanations why is not possible to use lambda in >>> "native" fashion. Anyway - I'm not describing my pain just to share >>> my pain - if anyone have any suggestions how this can be solved, I'm >>> all ears; any reply would be greatly appreciated. >>> >>> Thanks! >>> Pavel >>> >>> >>> On 12/03/14 19:42, Remi Forax wrote: >>>> On 03/12/2014 07:12 PM, Pavel Bucek wrote: >>>>> Hello all, >>>>> >>>>> I have an issue with getting generic parameter when using lambdas. >>>>> I can get the type when using anonymous classes. >>>>> >>>>> code sample will be more descriptive than anything I would say, >>>>> so.. : >>>>> >>>>> public class Main { >>>>> >>>>> public static interface A { >>>>> public void method(T param); >>>>> } >>>>> >>>>> public static void main(String[] args) { >>>>> >>>>> final A
anonClass = new A
() { >>>>> @Override >>>>> public void method(Main param) { >>>>> System.out.println("234"); >>>>> } >>>>> }; >>>>> >>>>> final A
lambda = param -> System.out.println("234"); >>>>> >>>>> //following does not help. >>>>> // final A
lambda = (A
)param -> >>>>> System.out.println("234"); >>>>> >>>>> >>>>> // output: Main.Main$A
>>>>> System.out.println("$ " + >>>>> anonClass.getClass().getGenericInterfaces()[0]); >>>>> >>>>> // output: interface Main$A ### generic type info >>>>> is already lost (no
) >>>>> System.out.println("# " + >>>>> lambda.getClass().getGenericInterfaces()[0]); >>>>> >>>>> // parameterized type from annon class >>>>> final Type t = >>>>> ((ParameterizedType)anonClass.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0]; >>>>> System.out.println("$ " + t); >>>>> >>>>> // parameterized type from lambda >>>>> System.out.println("# " + "???"); >>>>> } >>>>> } >>>>> >>>>> I was not able to find any useful documentation or article about >>>>> this, so sorry if this is something common - feel free to RTM me >>>>> (with relevant link please). >>>>> >>>>> Thanks and regards, >>>>> Pavel >>>> >>>> As you have seen a lambda is not an anonymous class :) >>>> >>>> A non-serializable lambda is more lightweight than an anonymous >>>> class so the generic information that are transmitted from the >>>> bytecode to the runtime (the lambda metafactory) are not kept >>>> inside the lambda class (a lambda class may be shared by several >>>> different lambdas). >>>> >>>> A serializable lambda keep these information because you need them >>>> to deserialize a lambda but they are not publicly available >>>> The current implementation encoded them in the bytecode and this >>>> bytecode is not publicly available so unless you serialize the >>>> lambda and serialize it by hand, you can not have access to these >>>> information. >>>> >>>> So you can not use a lambda with frameworks like Jackson that use >>>> the TypeReference idiom, >>>> you can still use an anonymous class for that :) >>>> >>>> cheers, >>>> R?mi >>>> >>>> >>>> >>> >>> >>> >> >> >> > From simone.bordet at gmail.com Fri Mar 14 22:07:53 2014 From: simone.bordet at gmail.com (Simone Bordet) Date: Fri, 14 Mar 2014 23:07:53 +0100 Subject: JDK 8 - Lambda - Reflection issues In-Reply-To: <532346F6.2040800@univ-mlv.fr> References: <5320A388.9030000@oracle.com> <5320AA7E.7060507@univ-mlv.fr> <532172BA.3070303@oracle.com> <532346F6.2040800@univ-mlv.fr> Message-ID: Hi, > On 03/13/2014 09:56 AM, Pavel Bucek wrote: >> I'm working on JSR 356 - Java API for WebSocket implementation and there >> is an interface: >> >> interface MessageHandler.Whole extends MessageHandler { >> void onMessage(T message); >> } >> >> And then there is a Session object, which has method "void >> addMessageHandler(MessageHandler handler);". Obvious common use of this >> method is: >> >> session.addMessageHandler(new MessageHandler.Whole() { >> @Override >> public void onMessage(String message) { >> // ... >> } >> }); >> >> I can see my IDE automatically offers me to transform this to lambda >> expression (this is actually what worries me a little, because all users >> will see that and do it - because why not - it seems to be equivalent with >> anonymous class). When this suggestion is accepted, previous statement is >> transformed into: >> >> session.addMessageHandler((MessageHandler.Whole) message -> { >> // ... >> }); As another co-implementor of JSR 356 in Jetty, I wanted to express the same concerns as Pavel. On Fri, Mar 14, 2014 at 7:14 PM, Remi Forax wrote: > I should have written a blog post on that subject a long time ago, > doing runtime inspection of type information used by javac in a library is > usually harmful, > here is why. > > 1) Java is not the only language on the JVM, the other compiler/runtime > doesn't necessarily have type information, > by requiring type information you consider groovy, nashorn, jruby, etc > guys as second citizens. Very good point. > 2) The code that does the introspection is hard to get right, > a simple example that shows that you have to do type propagation: > interface Foo extends MessageHandler.Whole { } > class Bar extends Comparable, Foo { ... } > session.addMessageHandler(new Bar()); > > 3) At runtime, it can be very slow because it may have to crawle all the > super types, > and look for a fix point when you have types that have recursive bounds > (like enums or comparable) > > 4) Let suppose the introspection code found a type, then it usually relies > on an implicit configuration > to find how to convert the value (usually a String) to the type. > Implicit configuration == nigthmare when testing if the configuration > used by the user code > is not the default one > > So instead of using a broken idiom, I think it's better to explicitly > specify the conversion > using either a lambda or better a method reference as first parameter. > > session.addMessageHandler(Integer:parseInt, integer -> ...); > session.addMessageHandler(Paths::get, path -> ...); In JSR 356 the type T in Whole is used to select a "deserializer" that converts the bytes in the WebSocket message to an object of type T. "Deserializers" are configurable by the application. If I understand correctly R?mi suggestion, he's saying to change the signature to accept a "converter" from String/byte[] to something (above expressed as a method reference) and then feed the result of that to the lambda. addMessageHandler(Function f, MessageHandler h) It would be probably much simpler to get rid of "deserializers" in JSR 356, and stick with String and byte[], and possibly streams and readers. The application does the rest. Not that it will fix the problem at hand, and just for sake of discussion, has the idea of an annotation that enforces *not* to convert to a lambda been explored by experts ? @NONFunctionalInterface interface Foo { void foo(T t); } interface Bar { void accept(Foo foo); } class Main { void main(String[] a) { Bar bar = ...; bar.accept((String s) -> { ... }); // Does not compile } } Thanks ! -- Simone Bordet http://bordet.blogspot.com --- Finally, no matter how good the architecture and design are, to deliver bug-free software with optimal performance and reliability, the implementation technique must be flawless. Victoria Livschitz From rednaxelafx at gmail.com Tue Mar 18 23:36:37 2014 From: rednaxelafx at gmail.com (Krystal Mok) Date: Tue, 18 Mar 2014 16:36:37 -0700 Subject: Question on binary compatibility regarding default methods Message-ID: Hi all, I'm curious about a corner case of binary compatibility with regard to default methods and separate compilation (the source of many evils...). The example is run with JDK 8 build 132. Description: The starting point is that I've got an interface and an implementation class: public interface IFoo { // empty } public class Foo implements IFoo { public void bar(Foo o) { System.out.println("Foo.bar(Foo)"); } } Both the interface and the implementation are compiled into Class files. Refer to this as ver1. Foo won't have any bridge methods on it at this point. Later on, the interface adds a default method, and is compiled separately, without recompiling the implementation class: public interface IFoo { default void bar(E e) { System.out.println("IFoo.bar(E)"); } } Refer to this as ver2. Then, another class uses the ver2 interface with the ver1 implementation class: public class Main { public static void main(String[] args) { Foo f = new Foo(); f.bar(f); // (1) invokevirtual Foo.bar(Foo)void IFoo i = f; i.bar(f); // (2) invokeinterface IFoo.bar(Object)void } } The output at (1) and (2) are: Foo.bar(Foo) IFoo.bar(E) My question is: is this the expected behavior according to the current spec, by design? I suppose it is. The implementation in HotSpot seems to be only using the erased (name, signature) of bar(Object)void when searching candidates, so naturally it won't find the Foo.bar(Foo), and it can't find a bridge method for that because of separate compilation. Thanks, Kris From jin.phd at gmail.com Wed Mar 19 10:10:11 2014 From: jin.phd at gmail.com (Jin Mingjian) Date: Wed, 19 Mar 2014 18:10:11 +0800 Subject: Question on binary compatibility regarding default methods In-Reply-To: References: Message-ID: Hi, Kris, It seemed a synthetic method was added when the "famous" Java generics joining. You may need to consult experts in lambda-dev at openjdk.java.net:) Jin On Wed, Mar 19, 2014 at 7:36 AM, Krystal Mok wrote: > Hi all, > > I'm curious about a corner case of binary compatibility with regard to > default methods and separate compilation (the source of many evils...). The > example is run with JDK 8 build 132. > > Description: > > The starting point is that I've got an interface and an implementation > class: > > public interface IFoo { > // empty > } > > public class Foo implements IFoo { > public void bar(Foo o) { > System.out.println("Foo.bar(Foo)"); > } > } > > Both the interface and the implementation are compiled into Class files. > Refer to this as ver1. > Foo won't have any bridge methods on it at this point. > > Later on, the interface adds a default method, and is compiled separately, > without recompiling the implementation class: > > public interface IFoo { > default void bar(E e) { > System.out.println("IFoo.bar(E)"); > } > } > > Refer to this as ver2. > > Then, another class uses the ver2 interface with the ver1 implementation > class: > > public class Main { > public static void main(String[] args) { > Foo f = new Foo(); > f.bar(f); // (1) invokevirtual Foo.bar(Foo)void > > IFoo i = f; > i.bar(f); // (2) invokeinterface IFoo.bar(Object)void > } > } > > The output at (1) and (2) are: > Foo.bar(Foo) > IFoo.bar(E) > > My question is: is this the expected behavior according to the current > spec, by design? I suppose it is. > > The implementation in HotSpot seems to be only using the erased (name, > signature) of bar(Object)void when searching candidates, so naturally it > won't find the Foo.bar(Foo), and it can't find a bridge method for that > because of separate compilation. > > Thanks, > Kris > From forax at univ-mlv.fr Wed Mar 19 10:15:08 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 19 Mar 2014 11:15:08 +0100 Subject: Question on binary compatibility regarding default methods In-Reply-To: References: Message-ID: <53296E2C.5000103@univ-mlv.fr> On 03/19/2014 12:36 AM, Krystal Mok wrote: > Hi all, > > I'm curious about a corner case of binary compatibility with regard to > default methods and separate compilation (the source of many evils...). The > example is run with JDK 8 build 132. > > Description: > > The starting point is that I've got an interface and an implementation > class: > > public interface IFoo { > // empty > } > > public class Foo implements IFoo { > public void bar(Foo o) { > System.out.println("Foo.bar(Foo)"); > } > } > > Both the interface and the implementation are compiled into Class files. > Refer to this as ver1. > Foo won't have any bridge methods on it at this point. > > Later on, the interface adds a default method, and is compiled separately, > without recompiling the implementation class: > > public interface IFoo { > default void bar(E e) { > System.out.println("IFoo.bar(E)"); > } > } > > Refer to this as ver2. > > Then, another class uses the ver2 interface with the ver1 implementation > class: > > public class Main { > public static void main(String[] args) { > Foo f = new Foo(); > f.bar(f); // (1) invokevirtual Foo.bar(Foo)void > > IFoo i = f; > i.bar(f); // (2) invokeinterface IFoo.bar(Object)void > } > } > > The output at (1) and (2) are: > Foo.bar(Foo) > IFoo.bar(E) > > My question is: is this the expected behavior according to the current > spec, by design? I suppose it is. yes > > The implementation in HotSpot seems to be only using the erased (name, > signature) of bar(Object)void when searching candidates, so naturally it > won't find the Foo.bar(Foo), and it can't find a bridge method for that > because of separate compilation. yes, as you note to solve this issue you have to teach the VM the precise semantics of Java generics. The lambda EG has initially though it was a good idea to solve this corner case so Keith McGuigan have done the daunting jobs to implement in the VM the generation of bridges with all the corner cases related to generics leading to awful issues like the fact that to generate bridges you have to load more classes than necessary. So we have backpedaled on that point considering that linking the VM semantics to the Java type system was wrong and even evil. It's obvious now and the lambda EG should have been more more clairvoyant on that point (sorry Keith). > > Thanks, > Kris cheers, R?mi From rednaxelafx at gmail.com Wed Mar 19 15:33:22 2014 From: rednaxelafx at gmail.com (Krystal Mok) Date: Wed, 19 Mar 2014 08:33:22 -0700 Subject: Question on binary compatibility regarding default methods In-Reply-To: <53296E2C.5000103@univ-mlv.fr> References: <53296E2C.5000103@univ-mlv.fr> Message-ID: Hi R?mi, Great! Thanks a lot for your answer. That's what I'm looking for. I do remember that at one point there was a piece of code in the VM that injected bridge methods, but I didn't follow the development of this area later, so I thought the VM was still doing that, but it isn't. So I was a bit confused and needed clarification. Now I've got it :-) Thanks, Kris On Wednesday, March 19, 2014, Remi Forax wrote: > On 03/19/2014 12:36 AM, Krystal Mok wrote: > >> Hi all, >> >> I'm curious about a corner case of binary compatibility with regard to >> default methods and separate compilation (the source of many evils...). >> The >> example is run with JDK 8 build 132. >> >> Description: >> >> The starting point is that I've got an interface and an implementation >> class: >> >> public interface IFoo { >> // empty >> } >> >> public class Foo implements IFoo { >> public void bar(Foo o) { >> System.out.println("Foo.bar(Foo)"); >> } >> } >> >> Both the interface and the implementation are compiled into Class files. >> Refer to this as ver1. >> Foo won't have any bridge methods on it at this point. >> >> Later on, the interface adds a default method, and is compiled separately, >> without recompiling the implementation class: >> >> public interface IFoo { >> default void bar(E e) { >> System.out.println("IFoo.bar(E)"); >> } >> } >> >> Refer to this as ver2. >> >> Then, another class uses the ver2 interface with the ver1 implementation >> class: >> >> public class Main { >> public static void main(String[] args) { >> Foo f = new Foo(); >> f.bar(f); // (1) invokevirtual Foo.bar(Foo)void >> >> IFoo i = f; >> i.bar(f); // (2) invokeinterface IFoo.bar(Object)void >> } >> } >> >> The output at (1) and (2) are: >> Foo.bar(Foo) >> IFoo.bar(E) >> >> My question is: is this the expected behavior according to the current >> spec, by design? I suppose it is. >> > > yes > > >> The implementation in HotSpot seems to be only using the erased (name, >> signature) of bar(Object)void when searching candidates, so naturally it >> won't find the Foo.bar(Foo), and it can't find a bridge method for that >> because of separate compilation. >> > > yes, > as you note to solve this issue you have to teach the VM the precise > semantics of Java generics. > The lambda EG has initially though it was a good idea to solve this corner > case so Keith McGuigan have done the daunting jobs to implement in the VM > the generation of bridges with all the corner cases related to generics > leading to awful issues like the fact that to generate bridges you have to > load more classes than necessary. > So we have backpedaled on that point considering that linking the VM > semantics to the Java type system was wrong and even evil. > > It's obvious now and the lambda EG should have been more more clairvoyant > on that point (sorry Keith). > > >> Thanks, >> Kris >> > > cheers, > R?mi > > From sundararajan.athijegannathan at oracle.com Fri Mar 21 15:12:39 2014 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Fri, 21 Mar 2014 20:42:39 +0530 Subject: [8u20] approval request for 8037562: Nashorn: JSON.parse comes up with nonexistent entries if there are gaps between the keys Message-ID: <532C56E7.6020003@oracle.com> Please approve backport of fix for JDK-8037562 to 8u20. Bug: https://bugs.openjdk.java.net/browse/JDK-8037562 Webrev: http://cr.openjdk.java.net/~sundar/8037562/ [same webrev sent for jdk9-dev. Applied "as is" with no changes to 8u20] Original review request: http://mail.openjdk.java.net/pipermail/nashorn-dev/2014-March/002839.html Thanks -Sundar From rob.mckenna at oracle.com Fri Mar 21 15:16:05 2014 From: rob.mckenna at oracle.com (Rob McKenna) Date: Fri, 21 Mar 2014 15:16:05 +0000 Subject: [8u20] approval request for 8037562: Nashorn: JSON.parse comes up with nonexistent entries if there are gaps between the keys In-Reply-To: <532C56E7.6020003@oracle.com> References: <532C56E7.6020003@oracle.com> Message-ID: <532C57B5.5030609@oracle.com> Approved. -Rob On 21/03/14 15:12, A. Sundararajan wrote: > Please approve backport of fix for JDK-8037562 to 8u20. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8037562 > Webrev: http://cr.openjdk.java.net/~sundar/8037562/ > > [same webrev sent for jdk9-dev. Applied "as is" with no changes to 8u20] > > Original review request: > > http://mail.openjdk.java.net/pipermail/nashorn-dev/2014-March/002839.html > > Thanks > -Sundar From paul.sandoz at oracle.com Mon Mar 24 16:00:05 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 24 Mar 2014 17:00:05 +0100 Subject: Backport Fwd: RFR 8037857: Methods j.u.Arrays.spliterator/stream(X[], int, int) throw IAE instead of specified AIOOBE when endIndex < startIndex References: Message-ID: <7B290BDF-2F7F-408F-82BD-AC9ED4631211@oracle.com> Hi, I would like to backport the following that has been approved for 9 to 8u20. Patch for 9 currently applies cleanly to 8u20. Thanks, Paul. Begin forwarded message: > From: Paul Sandoz > Subject: RFR 8037857: Methods j.u.Arrays.spliterator/stream(X[], int, int) throw IAE instead of specified AIOOBE when endIndex < startIndex > Date: March 24, 2014 12:44:45 PM GMT+01:00 > To: core-libs-dev Libs > > Hi, > > Simple patch to align code with spec for stream/spliterator factory methods on Arrays and spliterator methods on Spliterators, and make the next release of the JCK happy: > > http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8037857-spliterator-aioob/webrev/ > > After 9 it should go back to 8u20. > > Paul. From paul.sandoz at oracle.com Mon Mar 24 16:05:10 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 24 Mar 2014 17:05:10 +0100 Subject: Ignore Re: Backport Fwd: RFR 8037857: Methods j.u.Arrays.spliterator/stream(X[], int, int) throw IAE instead of specified AIOOBE when endIndex < startIndex In-Reply-To: <7B290BDF-2F7F-408F-82BD-AC9ED4631211@oracle.com> References: <7B290BDF-2F7F-408F-82BD-AC9ED4631211@oracle.com> Message-ID: <92CBD150-EBBC-49C7-8D8E-886336048C0E@oracle.com> Apologies, please ignore, missed the u in jdk8u-dev email address. Paul. On Mar 24, 2014, at 5:00 PM, Paul Sandoz wrote: > Hi, > > I would like to backport the following that has been approved for 9 to 8u20. Patch for 9 currently applies cleanly to 8u20. > > Thanks, > Paul. > > Begin forwarded message: > >> From: Paul Sandoz >> Subject: RFR 8037857: Methods j.u.Arrays.spliterator/stream(X[], int, int) throw IAE instead of specified AIOOBE when endIndex < startIndex >> Date: March 24, 2014 12:44:45 PM GMT+01:00 >> To: core-libs-dev Libs >> >> Hi, >> >> Simple patch to align code with spec for stream/spliterator factory methods on Arrays and spliterator methods on Spliterators, and make the next release of the JCK happy: >> >> http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8037857-spliterator-aioob/webrev/ >> >> After 9 it should go back to 8u20. >> >> Paul. > From fweimer at redhat.com Tue Mar 25 08:54:40 2014 From: fweimer at redhat.com (Florian Weimer) Date: Tue, 25 Mar 2014 09:54:40 +0100 Subject: JDK 8 - Lambda - Reflection issues In-Reply-To: <532172BA.3070303@oracle.com> References: <5320A388.9030000@oracle.com> <5320AA7E.7060507@univ-mlv.fr> <532172BA.3070303@oracle.com> Message-ID: <53314450.6040804@redhat.com> On 03/13/2014 09:56 AM, Pavel Bucek wrote: > And then there is a Session object, which has method "void > addMessageHandler(MessageHandler handler);". Obvious common use of this > method is: > > session.addMessageHandler(new MessageHandler.Whole() { > @Override > public void onMessage(String message) { > // ... > } > }); > > I can see my IDE automatically offers me to transform this to lambda > expression (this is actually what worries me a little, because all users > will see that and do it - because why not - it seems to be equivalent > with anonymous class). When this suggestion is accepted, previous > statement is transformed into: > > session.addMessageHandler((MessageHandler.Whole) message -> { > // ... > }); > > which looks prettier, but just does not work and cannot work :/ Why doesn't it work? Does the implementation try to extract the String actual type argument? Then it's unsound because session.addMessageHandler(new MessageHandler.Whole() { @Override public void onMessage(T message) { // ... } }); type-checks (assuming that T is a type parameter), but will not work at run time, either. -- Florian Weimer / Red Hat Product Security Team