From hannes.wallnoefer at oracle.com Tue Feb 3 11:25:07 2015 From: hannes.wallnoefer at oracle.com (Hannes Wallnoefer) Date: Tue, 03 Feb 2015 12:25:07 +0100 Subject: Review request for JDK-8062141: Various performance issues parsing JSON In-Reply-To: References: <54CBB41B.6020103@oracle.com> Message-ID: <54D0B013.2030703@oracle.com> Thanks a lot for the review, Marcus. Unfortunately I realized yesterday that my change is incomplete without a way to cache and reuse property maps. Not only will this make the parser itself faster, but without it code dealing with parsed JSON will become megamorphic very fast. I'll upload a new webrev soon. It will also address your comments below. Hannes Am 2015-01-31 um 16:40 schrieb Marcus Lagergren: > Stellar work, Hannes! And readable code. > > Awesome numbers, Hannes. Why was the last JSON parser so slow? I guess it was just a case of clean room implement per spec to ensure correctness, right? I don?t think we?ve paid a lot of attention to the JSON code since it was first written. > > Does everything compile without warnings? I notice you have explicitly added a @SuppressWarnings(?unchecked?) in JSONFunctions. Why was this the case? List still too weak? > > Do your ProperyHashMap changes give us benefits in performance elsewhere too? (or slowdowns for that matter) > > Do you have any micro benchmarks you used to test this to check in ? > > +1 > > /M > >> On 30 Jan 2015, at 17:40, Hannes Wallnoefer wrote >> >> Please review JDK-8062141: Various performance issues parsing JSON: >> >> http://cr.openjdk.java.net/~hannesw/8062141/ >> >> Thew new JSON parser is about 2-3 x faster than our old one, roughly on par with the ones in Rhino or V8. >> >> Hannes From michael.krause at grawe.at Tue Feb 3 12:26:54 2015 From: michael.krause at grawe.at (Krause, Michael) Date: Tue, 3 Feb 2015 12:26:54 +0000 Subject: Coercion of Java Enums works differently than in Rhino Message-ID: Hi, It seems that in Nashorn Java enums are no longer coerced into their string value: java.math.RoundingMode.UP == "UP" evaluates to true in Java 7 but to false in Java 8 when executed in the respective JavaScript engine. Does anybody know if this is actually a bug or just something in the specification? Thanks! Mit freundlichen Gr??en / Best regards Michael Kurt Krause ________________________________________ Grazer Wechselseitige Versicherung AG Pestalozzistra?e 73, 8011 Graz Tel.: +43 316 908031-6174 Fax: +43 316 80379 Mail: michael.krause at grawe.at Web: www.grawe.at FN 37748m, Landes- als Handelsgericht Graz Bitte denken Sie an die Umwelt, bevor Sie dieses E-Mail ausdrucken! From attila.szegedi at oracle.com Tue Feb 3 14:15:21 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Tue, 3 Feb 2015 15:15:21 +0100 Subject: Coercion of Java Enums works differently than in Rhino In-Reply-To: References: Message-ID: <9DF83C66-E76E-431E-86AC-CB31ACBC3A18@oracle.com> We debated this issue within the team, and it turned out to be a fairly deeper rabbit hole than initially expected. This comparison falls under the case 9 (Object compared to String) of the "The Abstract Equality Comparison Algorithm" . It requires that we invoke ToPrimitive(x), which in turn requires evaluation of [[DefaultValue]] internal property on the enum object. The behavior of [[DefaultValue]] on ordinary JS objects is described in and we could choose to follow it: if the object has a "toString" callable property, invoke it. So by that token, we could indeed invoke toString() on a POJO here. However, a runtime is at liberty to redefine [[DefaultValue]] for host objects too, with the restriction that "If a host object implements its own [[DefaultValue]] internal method, it must ensure that its [[DefaultValue]] internal method can return only primitive values." (still section 8.12.8). In ES5, any object not being a native JS object is a "host object" - all POJOs are considered host objects in Nashorn. Going to section 8.6.2, "Object Internal Properties and Methods" it says that every object (even host objects) must have all properties in Table 9 ? [[DefaultValue]] included, but also says: "However, the [[DefaultValue]] internal method may, for some objects, simply throw a TypeError exception." So with all that in mind, we have two choices for specification-compliant implementation of this comparison: 1. invoke toString() on the POJO when compared to a String (and everywhere else in the runtime where specification prescribes ToPrimitive() conversion ? this can have some ripple effects?), or 2. throw TypeError when toPrimitive(x) is invoked on a POJO. From this PoV, returning false from that comparison indeed seems incorrect; we should either return true, or throw a TypeError. Problem is, we have hard time deciding which way to go. JS is a very permissive language and it really allows you to convert almost anything to almost everything. While we're in the pure JS-land, we can't have a choice but to follow it. However, when it comes to the boundary of JS and Java, we are at a discretion to enforce slightly more explicit typing, should we choose to do so. If we choose option 1 above, then your example will return true, but there will potentially be a lot of implicit toString() invocations on POJOs in code people write. We're somewhat wary of all those implicit toString()s. If we choose option 2 above, then your example will throw TypeError and you will have to add an explicit .toString() invocation if you want to make it work. While 1 seems convenient, note also that in other comparison cases JS would prescribe ToPrimitive() with a Number hint, and we couldn't really provide that either as POJOs are not readily convertible to a number, so we'd have a coercion that works for string comparison, but not for number comparison, which'd feel inconsistent. Consistently throwing TypeError would at the very least force the developer to acknowledge that you'll be doing a conversion here, and accept its costs as some toString()s are costly. Or even use a method other than toString() (which is really more meant to be a debugging method on Object anyway); also if you'd compare against a number, it'd make you decide what (if anything) is the number value of your object. I'm throwing all this out here because we'd like to hear what the community thinks about which'd be the preferred way to go. Attila. On Feb 3, 2015, at 1:26 PM, Krause, Michael wrote: > Hi, > > It seems that in Nashorn Java enums are no longer coerced into their string value: > > java.math.RoundingMode.UP == "UP" > > evaluates to true in Java 7 but to false in Java 8 when executed in the respective JavaScript engine. > > > Does anybody know if this is actually a bug or just something in the specification? > > Thanks! > > > > Mit freundlichen Gr??en / Best regards > Michael Kurt Krause > ________________________________________ > > Grazer Wechselseitige Versicherung AG > Pestalozzistra?e 73, 8011 Graz > Tel.: +43 316 908031-6174 > Fax: +43 316 80379 > Mail: michael.krause at grawe.at > Web: www.grawe.at > > FN 37748m, Landes- als Handelsgericht Graz > Bitte denken Sie an die Umwelt, bevor Sie dieses E-Mail ausdrucken! From michael.krause at grawe.at Tue Feb 3 16:15:30 2015 From: michael.krause at grawe.at (Krause, Michael) Date: Tue, 3 Feb 2015 16:15:30 +0000 Subject: AW: Coercion of Java Enums works differently than in Rhino In-Reply-To: <9DF83C66-E76E-431E-86AC-CB31ACBC3A18@oracle.com> References: , <9DF83C66-E76E-431E-86AC-CB31ACBC3A18@oracle.com> Message-ID: Hi, thank you for the concise explanation! I understand that it is a difficult choice. I would vote for the TypeError, because I feel that all this implicit stuff can break easily. As it indeed did in my case. Also, since many shops have Java 8 in production right now, going for the TypeError will break existing scripts in an observable manner. Which is much better compared to silently changing behaviour, which will happen when you choose to invoke toString(). if this qualifies as a bug, could you please create one? Thank you! > ________________________________________ >Von: Attila Szegedi [attila.szegedi at oracle.com] >Gesendet: Dienstag, 3. Februar 2015 15:15 >An: Krause, Michael >Cc: nashorn-dev at openjdk.java.net >Betreff: Re: Coercion of Java Enums works differently than in Rhino >I'm throwing all this out here because we'd like to hear what the community thinks about which'd be the preferred way to go. > >Attila. > >On Feb 3, 2015, at 1:26 PM, Krause, Michael wrote: > >> Hi, >> >> It seems that in Nashorn Java enums are no longer coerced into their string value: >> >> java.math.RoundingMode.UP == "UP" >> >> evaluates to true in Java 7 but to false in Java 8 when executed in the respective JavaScript engine. >> >> >> Does anybody know if this is actually a bug or just something in the specification? >> >> Thanks! From attila.szegedi at oracle.com Tue Feb 3 18:24:09 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Tue, 3 Feb 2015 19:24:09 +0100 Subject: Coercion of Java Enums works differently than in Rhino In-Reply-To: References: , <9DF83C66-E76E-431E-86AC-CB31ACBC3A18@oracle.com> Message-ID: <69D8BED8-4F9E-465A-A28F-DB9BB45FEDD7@oracle.com> I definitely consider it to be a bug. Accepted behaviours would be to either return true (if ToPrimitive on a POJO is allowed) or throw a TypeError (if it isn't). Returning false is incorrect. I filed https://bugs.openjdk.java.net/browse/JDK-8072426 Attila. On Feb 3, 2015, at 5:15 PM, Krause, Michael wrote: > Hi, thank you for the concise explanation! > > [...] > if this qualifies as a bug, could you please create one? > Thank you! >> ________________________________________ >> Von: Attila Szegedi [attila.szegedi at oracle.com] >> Gesendet: Dienstag, 3. Februar 2015 15:15 >> An: Krause, Michael >> Cc: nashorn-dev at openjdk.java.net >> Betreff: Re: Coercion of Java Enums works differently than in Rhino >> I'm throwing all this out here because we'd like to hear what the community thinks about which'd be the preferred way to go. >> >> Attila. >> >> On Feb 3, 2015, at 1:26 PM, Krause, Michael wrote: >> >>> Hi, >>> >>> It seems that in Nashorn Java enums are no longer coerced into their string value: >>> >>> java.math.RoundingMode.UP == "UP" >>> >>> evaluates to true in Java 7 but to false in Java 8 when executed in the respective JavaScript engine. >>> >>> >>> Does anybody know if this is actually a bug or just something in the specification? >>> >>> Thanks! > > From hannes.wallnoefer at oracle.com Wed Feb 4 12:49:53 2015 From: hannes.wallnoefer at oracle.com (Hannes Wallnoefer) Date: Wed, 04 Feb 2015 13:49:53 +0100 Subject: Review request for JDK-8062141: Various performance issues parsing JSON In-Reply-To: References: <54CBB41B.6020103@oracle.com> Message-ID: <54D21571.7040205@oracle.com> I uploaded a new wevrev: http://cr.openjdk.java.net/~hannesw/8062141/webrev.02/ This version builds the property maps and value containers directly in the JSON parser, making use of PropertyMap's history feature to reuse maps. Answers to Marcus' questions are inline below. Am 2015-01-31 um 16:40 schrieb Marcus Lagergren: > Awesome numbers, Hannes. Why was the last JSON parser so slow? I guess it was just a case of clean room implement per spec to ensure correctness, right? I don?t think we?ve paid a lot of attention to the JSON code since it was first written. I couldn't find a single issue with the old parser, so it's more like a death from thousand cuts. There's certainly room for improvement, which is important as these are the same base classes used by our main parser. > > Does everything compile without warnings? I notice you have explicitly added a @SuppressWarnings(?unchecked?) in JSONFunctions. Why was this the case? List still too weak? You're right, that @SuppressWarnings was not needed. In any case I removed the code that used it in my rewrite :) > Do your ProperyHashMap changes give us benefits in performance elsewhere too? (or slowdowns for that matter) I did these changes while working on the JSONParser and they seemed to help. However, to be sure I wrote a PropertyHashMap microbenchmark and what I found is that while these changes make creation of PropertyHashMap slightly faster, they slightly slow down access of properties. Since the latter is probably more important in a longer running process I removed those changes from my new webrev. > Do you have any micro benchmarks you used to test this to check in ? I added one, it's in test/examples/json-parser-micro.js Hannes > > +1 > > /M > >> On 30 Jan 2015, at 17:40, Hannes Wallnoefer wrote >> >> Please review JDK-8062141: Various performance issues parsing JSON: >> >> http://cr.openjdk.java.net/~hannesw/8062141/ >> >> Thew new JSON parser is about 2-3 x faster than our old one, roughly on par with the ones in Rhino or V8. >> >> Hannes From marcus.lagergren at oracle.com Wed Feb 4 15:25:52 2015 From: marcus.lagergren at oracle.com (Marcus Lagergren) Date: Wed, 4 Feb 2015 16:25:52 +0100 Subject: Review request for JDK-8062141: Various performance issues parsing JSON In-Reply-To: <54D21571.7040205@oracle.com> References: <54CBB41B.6020103@oracle.com> <54D21571.7040205@oracle.com> Message-ID: +1! Nicely done. > On 04 Feb 2015, at 13:49, Hannes Wallnoefer wrote: > > I uploaded a new wevrev: > > http://cr.openjdk.java.net/~hannesw/8062141/webrev.02/ > > This version builds the property maps and value containers directly in the JSON parser, making use of PropertyMap's history feature to reuse maps. > > Answers to Marcus' questions are inline below. > > Am 2015-01-31 um 16:40 schrieb Marcus Lagergren: >> Awesome numbers, Hannes. Why was the last JSON parser so slow? I guess it was just a case of clean room implement per spec to ensure correctness, right? I don?t think we?ve paid a lot of attention to the JSON code since it was first written. > > I couldn't find a single issue with the old parser, so it's more like a death from thousand cuts. There's certainly room for improvement, which is important as these are the same base classes used by our main parser. >> >> Does everything compile without warnings? I notice you have explicitly added a @SuppressWarnings(?unchecked?) in JSONFunctions. Why was this the case? List still too weak? > You're right, that @SuppressWarnings was not needed. In any case I removed the code that used it in my rewrite :) > >> Do your ProperyHashMap changes give us benefits in performance elsewhere too? (or slowdowns for that matter) > I did these changes while working on the JSONParser and they seemed to help. However, to be sure I wrote a PropertyHashMap microbenchmark and what I found is that while these changes make creation of PropertyHashMap slightly faster, they slightly slow down access of properties. Since the latter is probably more important in a longer running process I removed those changes from my new webrev. > >> Do you have any micro benchmarks you used to test this to check in ? > > I added one, it's in test/examples/json-parser-micro.js > > Hannes > >> >> +1 >> >> /M >> >>> On 30 Jan 2015, at 17:40, Hannes Wallnoefer wrote >>> >>> Please review JDK-8062141: Various performance issues parsing JSON: >>> >>> http://cr.openjdk.java.net/~hannesw/8062141/ >>> >>> Thew new JSON parser is about 2-3 x faster than our old one, roughly on par with the ones in Rhino or V8. >>> >>> Hannes > From sundararajan.athijegannathan at oracle.com Thu Feb 5 08:25:15 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Thu, 05 Feb 2015 13:55:15 +0530 Subject: RFR 8072595: nashorn should not use obj.getClass() for null checks Message-ID: <54D328EB.5040200@oracle.com> Please review http://cr.openjdk.java.net/~sundar/8072595/ for https://bugs.openjdk.java.net/browse/JDK-8072595 See also: http://cr.openjdk.java.net/~shade/scratch/NullChecks.java PS. Piggybacking a script engine test (which fails in 8u31 but passes in 8u40 - not sure if we had a test to cover it and hence adding it) and couple of minor issues with sample code as well. Thanks, -Sundar From hannes.wallnoefer at oracle.com Thu Feb 5 08:47:42 2015 From: hannes.wallnoefer at oracle.com (Hannes Wallnoefer) Date: Thu, 05 Feb 2015 09:47:42 +0100 Subject: RFR 8072595: nashorn should not use obj.getClass() for null checks In-Reply-To: <54D328EB.5040200@oracle.com> References: <54D328EB.5040200@oracle.com> Message-ID: <54D32E2E.7070008@oracle.com> +1 Am 2015-02-05 um 09:25 schrieb A. Sundararajan: > Please review http://cr.openjdk.java.net/~sundar/8072595/ for > https://bugs.openjdk.java.net/browse/JDK-8072595 > > See also: http://cr.openjdk.java.net/~shade/scratch/NullChecks.java > > PS. Piggybacking a script engine test (which fails in 8u31 but passes > in 8u40 - not sure if we had a test to cover it and hence adding it) > and couple of minor issues with sample code as well. > > Thanks, > -Sundar From attila.szegedi at oracle.com Thu Feb 5 08:54:50 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Thu, 5 Feb 2015 09:54:50 +0100 Subject: RFR 8072595: nashorn should not use obj.getClass() for null checks In-Reply-To: <54D328EB.5040200@oracle.com> References: <54D328EB.5040200@oracle.com> Message-ID: Object.requireNonNull JavaDoc suggests that when it's used for constructor parameter validation it's used as the RHS of field assignments. So instead of Objects.requireNonNull(clazz); this.clazz = clazz; use this.clazz = Objects.requireNonNull(clazz); Obviously, this is no big deal, but the fact that requireNonNull returns its argument could be leveraged. Attila. On Feb 5, 2015, at 9:25 AM, A. Sundararajan wrote: > Please review http://cr.openjdk.java.net/~sundar/8072595/ for https://bugs.openjdk.java.net/browse/JDK-8072595 > > See also: http://cr.openjdk.java.net/~shade/scratch/NullChecks.java > > PS. Piggybacking a script engine test (which fails in 8u31 but passes in 8u40 - not sure if we had a test to cover it and hence adding it) and couple of minor issues with sample code as well. > > Thanks, > -Sundar From attila.szegedi at oracle.com Thu Feb 5 09:31:47 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Thu, 5 Feb 2015 10:31:47 +0100 Subject: Review request for JDK-8062141: Various performance issues parsing JSON In-Reply-To: <54D21571.7040205@oracle.com> References: <54CBB41B.6020103@oracle.com> <54D21571.7040205@oracle.com> Message-ID: <49B7F824-2056-43CC-8514-0A496F1D527F@oracle.com> +1; excellent work! On Feb 4, 2015, at 1:49 PM, Hannes Wallnoefer wrote: > I uploaded a new wevrev: > > http://cr.openjdk.java.net/~hannesw/8062141/webrev.02/ > > This version builds the property maps and value containers directly in the JSON parser, making use of PropertyMap's history feature to reuse maps. > > Answers to Marcus' questions are inline below. > > Am 2015-01-31 um 16:40 schrieb Marcus Lagergren: >> Awesome numbers, Hannes. Why was the last JSON parser so slow? I guess it was just a case of clean room implement per spec to ensure correctness, right? I don?t think we?ve paid a lot of attention to the JSON code since it was first written. > > I couldn't find a single issue with the old parser, so it's more like a death from thousand cuts. There's certainly room for improvement, which is important as these are the same base classes used by our main parser. >> >> Does everything compile without warnings? I notice you have explicitly added a @SuppressWarnings(?unchecked?) in JSONFunctions. Why was this the case? List still too weak? > You're right, that @SuppressWarnings was not needed. In any case I removed the code that used it in my rewrite :) > >> Do your ProperyHashMap changes give us benefits in performance elsewhere too? (or slowdowns for that matter) > I did these changes while working on the JSONParser and they seemed to help. However, to be sure I wrote a PropertyHashMap microbenchmark and what I found is that while these changes make creation of PropertyHashMap slightly faster, they slightly slow down access of properties. Since the latter is probably more important in a longer running process I removed those changes from my new webrev. > >> Do you have any micro benchmarks you used to test this to check in ? > > I added one, it's in test/examples/json-parser-micro.js > > Hannes > >> >> +1 >> >> /M >> >>> On 30 Jan 2015, at 17:40, Hannes Wallnoefer wrote >>> >>> Please review JDK-8062141: Various performance issues parsing JSON: >>> >>> http://cr.openjdk.java.net/~hannesw/8062141/ >>> >>> Thew new JSON parser is about 2-3 x faster than our old one, roughly on par with the ones in Rhino or V8. >>> >>> Hannes > From hannes.wallnoefer at oracle.com Thu Feb 5 09:48:15 2015 From: hannes.wallnoefer at oracle.com (Hannes Wallnoefer) Date: Thu, 05 Feb 2015 10:48:15 +0100 Subject: Review request for JDK-8068872: Nashorn JSON.parse drops numeric keys Message-ID: <54D33C5F.7030209@oracle.com> Please review JDK-8068872: Nashorn JSON.parse drops numeric keys: http://cr.openjdk.java.net/~hannesw/8068872/ The main issue here was that ArrayData.ensure should only update the length if the new index is greater or equal to the old length. I also fixed two other related issues: - ScriptObject.defineProperty(int, Object) must call doesNotHaveEnsureDelete (which marks new unused slots as deleted) after having called ensure. - There's no need to call ensure(length - 1) on a newly created ArrayData(length). I've removed two such cases. Thanks, Hannes From attila.szegedi at oracle.com Thu Feb 5 09:55:49 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Thu, 5 Feb 2015 10:55:49 +0100 Subject: Review request for JDK-8068872: Nashorn JSON.parse drops numeric keys In-Reply-To: <54D33C5F.7030209@oracle.com> References: <54D33C5F.7030209@oracle.com> Message-ID: +1, looks good. Array handling can have sensitive corner cases - I presume you've run octane and test262 on this? Will also be curious about Marcus' review (he dealt a lot with arrays in the past). On Feb 5, 2015, at 10:48 AM, Hannes Wallnoefer wrote: > Please review JDK-8068872: Nashorn JSON.parse drops numeric keys: > > http://cr.openjdk.java.net/~hannesw/8068872/ > > The main issue here was that ArrayData.ensure should only update the length if the new index is greater or equal to the old length. > > I also fixed two other related issues: > > - ScriptObject.defineProperty(int, Object) must call doesNotHaveEnsureDelete (which marks new unused slots as deleted) after having called ensure. > - There's no need to call ensure(length - 1) on a newly created ArrayData(length). I've removed two such cases. > > Thanks, > Hannes From hannes.wallnoefer at oracle.com Thu Feb 5 10:05:36 2015 From: hannes.wallnoefer at oracle.com (Hannes Wallnoefer) Date: Thu, 05 Feb 2015 11:05:36 +0100 Subject: Review request for JDK-8068872: Nashorn JSON.parse drops numeric keys In-Reply-To: References: <54D33C5F.7030209@oracle.com> Message-ID: <54D34070.9080901@oracle.com> Yes, test262 and octane run fine. One pecularity I found is that ensure(newIndex) usually only needs to be called if newIndex >= length. But this is not true for SparseArray, as newIndex may be smaller than the sparse array's length but still greater than the underlying dense array's length/capacity. SparseArray handles this by calling its ensure method in various places where other ArrayData classes don't. Now that I think of it I will add a comment about this to SparseArray.ensure. Hannes Am 2015-02-05 um 10:55 schrieb Attila Szegedi: > +1, looks good. Array handling can have sensitive corner cases - I presume you've run octane and test262 on this? Will also be curious about Marcus' review (he dealt a lot with arrays in the past). > > On Feb 5, 2015, at 10:48 AM, Hannes Wallnoefer wrote: > >> Please review JDK-8068872: Nashorn JSON.parse drops numeric keys: >> >> http://cr.openjdk.java.net/~hannesw/8068872/ >> >> The main issue here was that ArrayData.ensure should only update the length if the new index is greater or equal to the old length. >> >> I also fixed two other related issues: >> >> - ScriptObject.defineProperty(int, Object) must call doesNotHaveEnsureDelete (which marks new unused slots as deleted) after having called ensure. >> - There's no need to call ensure(length - 1) on a newly created ArrayData(length). I've removed two such cases. >> >> Thanks, >> Hannes From marcus.lagergren at oracle.com Thu Feb 5 12:48:49 2015 From: marcus.lagergren at oracle.com (Marcus Lagergren) Date: Thu, 5 Feb 2015 13:48:49 +0100 Subject: Review request for JDK-8068872: Nashorn JSON.parse drops numeric keys In-Reply-To: <54D33C5F.7030209@oracle.com> References: <54D33C5F.7030209@oracle.com> Message-ID: <5DB1FC2E-82BC-4291-958F-BCBB86DB9911@oracle.com> +1 > On 05 Feb 2015, at 10:48, Hannes Wallnoefer wrote: > > Please review JDK-8068872: Nashorn JSON.parse drops numeric keys: > > http://cr.openjdk.java.net/~hannesw/8068872/ > > The main issue here was that ArrayData.ensure should only update the length if the new index is greater or equal to the old length. > > I also fixed two other related issues: > > - ScriptObject.defineProperty(int, Object) must call doesNotHaveEnsureDelete (which marks new unused slots as deleted) after having called ensure. > - There's no need to call ensure(length - 1) on a newly created ArrayData(length). I've removed two such cases. > > Thanks, > Hannes From sundararajan.athijegannathan at oracle.com Thu Feb 5 13:22:49 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Thu, 05 Feb 2015 18:52:49 +0530 Subject: RFR 8072595: nashorn should not use obj.getClass() for null checks In-Reply-To: References: <54D328EB.5040200@oracle.com> Message-ID: <54D36EA9.9010801@oracle.com> Updated it http://cr.openjdk.java.net/~sundar/8072595/webrev.01/ Thanks, -Sundar On Thursday 05 February 2015 02:24 PM, Attila Szegedi wrote: > Object.requireNonNull JavaDoc suggests that when it's used for constructor parameter validation it's used as the RHS of field assignments. So instead of > > Objects.requireNonNull(clazz); > this.clazz = clazz; > > use > > this.clazz = Objects.requireNonNull(clazz); > > Obviously, this is no big deal, but the fact that requireNonNull returns its argument could be leveraged. > > Attila. > > On Feb 5, 2015, at 9:25 AM, A. Sundararajan wrote: > >> Please review http://cr.openjdk.java.net/~sundar/8072595/ for https://bugs.openjdk.java.net/browse/JDK-8072595 >> >> See also: http://cr.openjdk.java.net/~shade/scratch/NullChecks.java >> >> PS. Piggybacking a script engine test (which fails in 8u31 but passes in 8u40 - not sure if we had a test to cover it and hence adding it) and couple of minor issues with sample code as well. >> >> Thanks, >> -Sundar From hannes.wallnoefer at oracle.com Thu Feb 5 15:04:51 2015 From: hannes.wallnoefer at oracle.com (Hannes Wallnoefer) Date: Thu, 05 Feb 2015 16:04:51 +0100 Subject: Review request for JDK-8072626: Test for JDK-8068872 fails in tip Message-ID: <54D38693.60100@oracle.com> Please review JDK-8072626: Test for JDK-8068872 fails in tip: http://cr.openjdk.java.net/~hannesw/8072626/ Thanks, Hannes From marcus.lagergren at oracle.com Thu Feb 5 15:55:34 2015 From: marcus.lagergren at oracle.com (Marcus Lagergren) Date: Thu, 5 Feb 2015 16:55:34 +0100 Subject: Review request for JDK-8072626: Test for JDK-8068872 fails in tip In-Reply-To: <54D38693.60100@oracle.com> References: <54D38693.60100@oracle.com> Message-ID: +1 > On 05 Feb 2015, at 16:04, Hannes Wallnoefer wrote: > > Please review JDK-8072626: Test for JDK-8068872 fails in tip: > > http://cr.openjdk.java.net/~hannesw/8072626/ > > Thanks, > Hannes From james.laskey at oracle.com Thu Feb 5 16:00:10 2015 From: james.laskey at oracle.com (Jim Laskey (Oracle)) Date: Thu, 5 Feb 2015 12:00:10 -0400 Subject: Review request for JDK-8072626: Test for JDK-8068872 fails in tip In-Reply-To: <54D38693.60100@oracle.com> References: <54D38693.60100@oracle.com> Message-ID: +1 On Feb 5, 2015, at 11:04 AM, Hannes Wallnoefer wrote: > Please review JDK-8072626: Test for JDK-8068872 fails in tip: > > http://cr.openjdk.java.net/~hannesw/8072626/ > > Thanks, > Hannes From christopherbrown06 at gmail.com Fri Feb 6 09:05:36 2015 From: christopherbrown06 at gmail.com (Christopher Brown) Date: Fri, 6 Feb 2015 10:05:36 +0100 Subject: Using Nashorn with interfaces loaded from custom classloaders Message-ID: Hello, Is it possible to use the Java.type() then the Java.extend() syntax described here: https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions ...with interface types loaded from a classloader other than the JRE classloader and the main application classloader. As a simple example, suppose in the main() method of an application, I create a URL classloader to load arbitrary JAR files containing interface definitions, and then I create an instance of the Nashorn scripting engine. Is it possible to make these types visible to the scripting engine, such that I could (in a loaded script) use Java.type() then Java.extend() to create an implementation of such a dynamically-loaded interface, and return it from the script when invoking a given function? I'm guessing that it's not possible, because I've not seen this documented anywhere. I would assume that it might be possible via the "context classloader" of the current thread, but I'd prefer not to rely on undocumented features (supposing that it's the case). The most flexible approach would be to pass a classloader (or a map/array of classloaders) into the binding, and pass it as a second parameter to the Java.type() function (especially if in a more complicated example, multiple URL classloaders were loaded and defined types with the same fully-qualified names). Additional question #1: would the implementation of the interface in Nashorn require that I implement default methods, or could they be invoked in the script without defining them? Additional question #2: how should resources added to a binding, and more generally, resources used by a ScriptEngine instance, be cleaned up when the engine instance is no longer required? For example, if adding classloaders is (or can be made) possible, I can't see any way to explicitly "close" the script engine... I'm assuming the only way to clean things up is to de-reference the engine and wait for it to be garbage-collected. Thanks, Christopher From sundararajan.athijegannathan at oracle.com Fri Feb 6 13:38:30 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Fri, 06 Feb 2015 19:08:30 +0530 Subject: RFR 8071989: NashornScriptEngine returns javax.script.ScriptContext instance with insonsistent get/remove methods behavior for undefined attributes Message-ID: <54D4C3D6.8020805@oracle.com> Please review http://cr.openjdk.java.net/~sundar/8071989/ for https://bugs.openjdk.java.net/browse/JDK-8071989 PS. Piggybacking a sample script - getclassnpe.js - to detect obj.getClass() call for null checks. Ran that on nashorn code and fixed one more such instance which got missed in the last clean-up with JDK-8072595 Thanks, -Sundar From marcus.lagergren at oracle.com Fri Feb 6 14:09:06 2015 From: marcus.lagergren at oracle.com (Marcus Lagergren) Date: Fri, 6 Feb 2015 15:09:06 +0100 Subject: RFR 8071989: NashornScriptEngine returns javax.script.ScriptContext instance with insonsistent get/remove methods behavior for undefined attributes In-Reply-To: <54D4C3D6.8020805@oracle.com> References: <54D4C3D6.8020805@oracle.com> Message-ID: +1 > On 06 Feb 2015, at 14:38, A. Sundararajan wrote: > > Please review http://cr.openjdk.java.net/~sundar/8071989/ for https://bugs.openjdk.java.net/browse/JDK-8071989 > > PS. Piggybacking a sample script - getclassnpe.js - to detect obj.getClass() call for null checks. Ran that on nashorn code and fixed one more such instance which got missed in the last clean-up with JDK-8072595 > > Thanks, > -Sundar From sundararajan.athijegannathan at oracle.com Mon Feb 9 08:57:47 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Mon, 09 Feb 2015 14:27:47 +0530 Subject: RFR 8072752: Add regression tests for 8071678 and 8071594 Message-ID: <54D8768B.2080507@oracle.com> Please review http://cr.openjdk.java.net/~sundar/8072752/ for https://bugs.openjdk.java.net/browse/JDK-8072752 Thanks, -Sundar From hannes.wallnoefer at oracle.com Mon Feb 9 09:08:11 2015 From: hannes.wallnoefer at oracle.com (Hannes Wallnoefer) Date: Mon, 09 Feb 2015 10:08:11 +0100 Subject: RFR 8072752: Add regression tests for 8071678 and 8071594 In-Reply-To: <54D8768B.2080507@oracle.com> References: <54D8768B.2080507@oracle.com> Message-ID: <54D878FB.3050805@oracle.com> +1 Am 2015-02-09 um 09:57 schrieb A. Sundararajan: > Please review http://cr.openjdk.java.net/~sundar/8072752/ for > https://bugs.openjdk.java.net/browse/JDK-8072752 > > Thanks, > -Sundar > From attila.szegedi at oracle.com Mon Feb 9 09:18:48 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Mon, 9 Feb 2015 10:18:48 +0100 Subject: RFR 8072752: Add regression tests for 8071678 and 8071594 In-Reply-To: <54D8768B.2080507@oracle.com> References: <54D8768B.2080507@oracle.com> Message-ID: <7A67B723-8E46-4552-AB05-13315A4B0FEB@oracle.com> +1 On Feb 9, 2015, at 9:57 AM, A. Sundararajan wrote: > Please review http://cr.openjdk.java.net/~sundar/8072752/ for https://bugs.openjdk.java.net/browse/JDK-8072752 > > Thanks, > -Sundar > From sergey.lugovoy at oracle.com Mon Feb 9 13:38:49 2015 From: sergey.lugovoy at oracle.com (Sergey Lugovoy) Date: Mon, 09 Feb 2015 16:38:49 +0300 Subject: RFR 8069182: Nightly test results are empty for targets test262/markdown/testjfx In-Reply-To: <54BCFD4A.4050205@oracle.com> References: <54BCFD4A.4050205@oracle.com> Message-ID: <54D8B869.3040402@oracle.com> Hi, please review these simple changes On 19.01.2015 15:49, Sergey Lugovoy wrote: > Please review http://cr.openjdk.java.net/~slugovoy/8069182/webrev.00/ > for https://bugs.openjdk.java.net/browse/JDK-8069182 > -- Thanks, Sergey From marcus.lagergren at oracle.com Mon Feb 9 13:53:50 2015 From: marcus.lagergren at oracle.com (Marcus Lagergren) Date: Mon, 9 Feb 2015 14:53:50 +0100 Subject: RFR 8069182: Nightly test results are empty for targets test262/markdown/testjfx In-Reply-To: <54BCFD4A.4050205@oracle.com> References: <54BCFD4A.4050205@oracle.com> Message-ID: <31D93A4C-C5BC-4DAA-919C-067B2544A9A2@oracle.com> +1 if everything works from the command line with ant test and so on. /M > On 19 Jan 2015, at 13:49, Sergey Lugovoy wrote: > > Please review http://cr.openjdk.java.net/~slugovoy/8069182/webrev.00/ for https://bugs.openjdk.java.net/browse/JDK-8069182 > > -- > Thanks, > Sergey > From sundararajan.athijegannathan at oracle.com Mon Feb 9 14:27:48 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Mon, 09 Feb 2015 19:57:48 +0530 Subject: RFR 8069182: Nightly test results are empty for targets test262/markdown/testjfx In-Reply-To: <54D8B869.3040402@oracle.com> References: <54BCFD4A.4050205@oracle.com> <54D8B869.3040402@oracle.com> Message-ID: <54D8C3E4.9030007@oracle.com> +1 -Sundar On Monday 09 February 2015 07:08 PM, Sergey Lugovoy wrote: > Hi, > please review these simple changes > > On 19.01.2015 15:49, Sergey Lugovoy wrote: >> Please review http://cr.openjdk.java.net/~slugovoy/8069182/webrev.00/ >> for https://bugs.openjdk.java.net/browse/JDK-8069182 >> > From dk068x at att.com Mon Feb 9 21:46:32 2015 From: dk068x at att.com (KARR, DAVID) Date: Mon, 9 Feb 2015 21:46:32 +0000 Subject: Using Nashorn for a general-purpose JavaScript AST handler? Message-ID: >From time to time, I've looked at using PMD for various metadata scanners for Java code. It's very easy to define callbacks for various syntax elements and then gather data from those found elements. I'm starting to see people looking at doing similar things for JavaScript code. Is there a straightforward way to use Nashorn to do this kind of thing? From sundararajan.athijegannathan at oracle.com Tue Feb 10 02:03:08 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Tue, 10 Feb 2015 07:33:08 +0530 Subject: Using Nashorn for a general-purpose JavaScript AST handler? In-Reply-To: References: Message-ID: <54D966DC.3070102@oracle.com> Hi, Nashorn parser API (http://openjdk.java.net/jeps/236) will be pushed shortly to jdk9. That should help with these use cases. In the meanwhile, there is script API for parsing. This is loaded and called using load("nashorn:parser.js") and calling top level function "parse". For a sample, please try this one: http://hg.openjdk.java.net/jdk9/dev/nashorn/file/2feff3616ba7/samples/astviewer.js Hope this helps, -Sundar On Tuesday 10 February 2015 03:16 AM, KARR, DAVID wrote: > From time to time, I've looked at using PMD for various metadata scanners for Java code. It's very easy to define callbacks for various syntax elements and then gather data from those found elements. I'm starting to see people looking at doing similar things for JavaScript code. Is there a straightforward way to use Nashorn to do this kind of thing? From attila.szegedi at oracle.com Wed Feb 11 08:56:36 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Wed, 11 Feb 2015 09:56:36 +0100 Subject: Using Nashorn with interfaces loaded from custom classloaders In-Reply-To: References: Message-ID: Java.type will only resolve names against script engine's "app loader" (which is whatever was the thread context loader at the time engine instance was created) and additionally from the path passed in as "-classpath" command line option (to get an engine with extra command line options programmatically you'll need to use NashornScriptEngineFactory class directly instead of only relying on javax.script.* APIs; actually you can pass explicit "app loader" with some of NashornScriptEngineFactory factory methods too). In absence of this, you can do the following: if you pass in a Class object representing your interface (let's call it ForeignInterface) into the runtime somehow (e.g. through Bindings): bindings.put("foreignInterfaceClass", ForeignInterface.class) then you can use "foreignInterfaceClass.static" to represent the static aspect of the type[1] in the script. Thereafter, var ForeignInterface = foreignInterfaceClass.static; var adapter = Java.extend(ForeignInterface ... should work, with the caveat that Nashorn's own classes must be visible through the class loader for ForeignInterface, as Nashorn will essentially be loading an adapter class that will have an "implements ForeignInterface" clause but it will also rely on some Nashorn internals in its bytecode, so it must be able to resolve symbolic bytecode references both to ForeignInterface and to some Nashorn classes. If your class loader has the extension class loader (which is where Nashorn lives) somewhere in its parent chain, you're good. Otherwise, if you have some more involved class loader topology, then I'm sorry to say that you're out of luck[2] :-( As for your additional questions: #1 you can decide to not implement all methods of the interface (in fact, you could choose to implement none of them :-) ). If the underlying script object provides no implementation for an invoked method, then interface default method is invoked if one is provided by the interface, otherwise java.lang.UnsupportedOperationException is thrown. #2 yes, javax.script has no explicit cleanup mechanism for script engines. It gets GC'd if it's unreachable. If you need resource cleanup tied to it not being reachable anymore, you'll need to use PhantomReference. HTH, Attila. --- [1] the one you would in Java simply call "ForeignInterface", except in Java it's not a reified object, but purely a lexical language construct. In Nashorn, static types are reified, and you can think of ".static" as being the inverse operation of ".class"; .class on a static type gives you a runtime type (java.lang.Class) object, while .static on a j.l.Class object gives you back the static type which is used as both the constructor function for the type and a namespace for static fields/properties/methods (just as in Java). This whole discussion about static types makes me want to extend the Java.extend so that it accepts either a static type or a runtime j.l.Class object in its arguments, though. [2] The truth is actually somewhat more complex; when Nashorn defines the adapter class, it does so in a small new class loader, and it needs to find a suitable parent for this class loader: one that sees the class being extended (if there's one), all the interface(s) being implemented, and the Nashorn classes themselves. This can get tricky if you're implementing multiple interfaces coming from multiple class loaders. Nashorn will choose a class loader from among all involved classes' and interfaces' class loaders that can see all the classes (the "maximum visibility class loader") by probing Class.forName from one loader with a name of a class from another loader and seeing if it resolves to the same class. If it finds one, it uses that as the parent loader for the adapter's loader. If it can't find one, you get a TypeError at runtime. You know I have a fun job when some days I wake up thinking "I need to write an algorithm for finding a maximum in a lattice of ClassLoader objects partially ordered by can-see-classes-in-the-other relation". On Feb 6, 2015, at 10:05 AM, Christopher Brown wrote: > Hello, > > Is it possible to use the Java.type() then the Java.extend() syntax > described here: > https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions > > ...with interface types loaded from a classloader other than the JRE > classloader and the main application classloader. > > As a simple example, suppose in the main() method of an application, I > create a URL classloader to load arbitrary JAR files containing interface > definitions, and then I create an instance of the Nashorn scripting > engine. Is it possible to make these types visible to the scripting > engine, such that I could (in a loaded script) use Java.type() then > Java.extend() to create an implementation of such a dynamically-loaded > interface, and return it from the script when invoking a given function? > > I'm guessing that it's not possible, because I've not seen this documented > anywhere. I would assume that it might be possible via the "context > classloader" of the current thread, but I'd prefer not to rely on > undocumented features (supposing that it's the case). The most flexible > approach would be to pass a classloader (or a map/array of classloaders) > into the binding, and pass it as a second parameter to the Java.type() > function (especially if in a more complicated example, multiple URL > classloaders were loaded and defined types with the same fully-qualified > names). > > Additional question #1: would the implementation of the interface in > Nashorn require that I implement default methods, or could they be invoked > in the script without defining them? > > Additional question #2: how should resources added to a binding, and more > generally, resources used by a ScriptEngine instance, be cleaned up when > the engine instance is no longer required? For example, if adding > classloaders is (or can be made) possible, I can't see any way to > explicitly "close" the script engine... I'm assuming the only way to clean > things up is to de-reference the engine and wait for it to be > garbage-collected. > > Thanks, > Christopher From attila.szegedi at oracle.com Wed Feb 11 18:35:45 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Wed, 11 Feb 2015 19:35:45 +0100 Subject: Review request for JDK-8072596 Message-ID: <85567C02-9C95-42F9-8196-F66DF6F27973@oracle.com> Please review JDK-8072596 at for Thanks, Attila. From marcus.lagergren at oracle.com Wed Feb 11 18:41:47 2015 From: marcus.lagergren at oracle.com (Marcus Lagergren) Date: Wed, 11 Feb 2015 19:41:47 +0100 Subject: Review request for JDK-8072596 In-Reply-To: <85567C02-9C95-42F9-8196-F66DF6F27973@oracle.com> References: <85567C02-9C95-42F9-8196-F66DF6F27973@oracle.com> Message-ID: <40F9446E-00B3-4410-A02B-DE31A38A2F11@oracle.com> +1 Nicely done! > On 11 Feb 2015, at 19:35, Attila Szegedi wrote: > > Please review JDK-8072596 at for > > Thanks, > Attila. From sundararajan.athijegannathan at oracle.com Thu Feb 12 15:28:54 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Thu, 12 Feb 2015 20:58:54 +0530 Subject: Review request for JDK-8072596 In-Reply-To: <85567C02-9C95-42F9-8196-F66DF6F27973@oracle.com> References: <85567C02-9C95-42F9-8196-F66DF6F27973@oracle.com> Message-ID: <54DCC6B6.5060609@oracle.com> +1 Nice work! -Sundar On Thursday 12 February 2015 12:05 AM, Attila Szegedi wrote: > Please review JDK-8072596 at for > > Thanks, > Attila. From sundararajan.athijegannathan at oracle.com Thu Feb 12 15:39:06 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Thu, 12 Feb 2015 21:09:06 +0530 Subject: Review request for JDK-8072596 In-Reply-To: <54DCC6B6.5060609@oracle.com> References: <85567C02-9C95-42F9-8196-F66DF6F27973@oracle.com> <54DCC6B6.5060609@oracle.com> Message-ID: <54DCC91A.5060509@oracle.com> Forgot to add. Few new files have old copyright year (like Jdk8072596TestSubject.java). Also the samples may be restored to use Arrays.asList (now that you've fixed the problem) diff -r 99cdacecab0a samples/javashell.js --- a/samples/javashell.js Tue Feb 10 13:10:07 2015 +0300 +++ b/samples/javashell.js Thu Feb 12 21:08:06 2015 +0530 @@ -122,7 +122,7 @@ // execute code command function exec(args) { // build child process and start it! - new ProcessBuilder(Java.to(args.split(' '), List)) + new ProcessBuilder(Arrays.asList(args.split(' '))) .inheritIO() .start() .waitFor(); diff -r 99cdacecab0a samples/shell.js --- a/samples/shell.js Tue Feb 10 13:10:07 2015 +0300 +++ b/samples/shell.js Thu Feb 12 21:08:06 2015 +0530 @@ -67,7 +67,7 @@ } } else { // build child process and start it! - new ProcessBuilder(Java.to(args, List)) + new ProcessBuilder(Arrays.asList(args)) .inheritIO() .start() .waitFor(); Thanks -Sundar On Thursday 12 February 2015 08:58 PM, A. Sundararajan wrote: > +1 > > Nice work! > > -Sundar > > On Thursday 12 February 2015 12:05 AM, Attila Szegedi wrote: >> Please review JDK-8072596 at >> for >> >> >> Thanks, >> Attila. > From christopherbrown06 at gmail.com Sun Feb 15 14:46:04 2015 From: christopherbrown06 at gmail.com (Christopher Brown) Date: Sun, 15 Feb 2015 15:46:04 +0100 Subject: Using Nashorn with interfaces loaded from custom classloaders In-Reply-To: References: Message-ID: Hello, Setting the context classloader when instantiating the script engine, as you suggested, solved my problem (note: the ScriptEngineManager had to be instantiated before changing the context classloader, as otherwise the "nashorn" engine couldn't be found). Here's the code: ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); thread.setContextClassLoader(MyApiInterface.class.getClassLoader()); ScriptEngine engine = scriptEngineManager.getEngineByName("nashorn"); thread.setContextClassLoader(contextClassLoader); Will this technique supported in the future (all foreseeable versions), or is it an implementation side-effect that is subject to change? Following on from your reply, making Java.type(...) accept an actual Class instance would be great. Also, a variant, such as: Java.type(className, classLoaderOrArrayOfClassLoaders) ...would be great. Thank you for your very helpful answer! -- Christopher On 11 February 2015 at 09:56, Attila Szegedi wrote: > Java.type will only resolve names against script engine's "app loader" > (which is whatever was the thread context loader at the time engine > instance was created) and additionally from the path passed in as > "-classpath" command line option (to get an engine with extra command line > options programmatically you'll need to use NashornScriptEngineFactory > class directly instead of only relying on javax.script.* APIs; actually you > can pass explicit "app loader" with some of NashornScriptEngineFactory > factory methods too). > > In absence of this, you can do the following: if you pass in a Class > object representing your interface (let's call it ForeignInterface) into > the runtime somehow (e.g. through Bindings): > > bindings.put("foreignInterfaceClass", ForeignInterface.class) > > then you can use "foreignInterfaceClass.static" to represent the static > aspect of the type[1] in the script. Thereafter, > > var ForeignInterface = foreignInterfaceClass.static; > var adapter = Java.extend(ForeignInterface ... > > should work, with the caveat that Nashorn's own classes must be visible > through the class loader for ForeignInterface, as Nashorn will essentially > be loading an adapter class that will have an "implements ForeignInterface" > clause but it will also rely on some Nashorn internals in its bytecode, so > it must be able to resolve symbolic bytecode references both to > ForeignInterface and to some Nashorn classes. If your class loader has the > extension class loader (which is where Nashorn lives) somewhere in its > parent chain, you're good. Otherwise, if you have some more involved class > loader topology, then I'm sorry to say that you're out of luck[2] :-( > > As for your additional questions: > > #1 you can decide to not implement all methods of the interface (in fact, > you could choose to implement none of them :-) ). If the underlying script > object provides no implementation for an invoked method, then interface > default method is invoked if one is provided by the interface, otherwise > java.lang.UnsupportedOperationException is thrown. > > #2 yes, javax.script has no explicit cleanup mechanism for script engines. > It gets GC'd if it's unreachable. If you need resource cleanup tied to it > not being reachable anymore, you'll need to use PhantomReference. > > HTH, > Attila. > > --- > [1] the one you would in Java simply call "ForeignInterface", except in > Java it's not a reified object, but purely a lexical language construct. In > Nashorn, static types are reified, and you can think of ".static" as being > the inverse operation of ".class"; .class on a static type gives you a > runtime type (java.lang.Class) object, while .static on a j.l.Class object > gives you back the static type which is used as both the constructor > function for the type and a namespace for static fields/properties/methods > (just as in Java). This whole discussion about static types makes me want > to extend the Java.extend so that it accepts either a static type or a > runtime j.l.Class object in its arguments, though. > > [2] The truth is actually somewhat more complex; when Nashorn defines the > adapter class, it does so in a small new class loader, and it needs to find > a suitable parent for this class loader: one that sees the class being > extended (if there's one), all the interface(s) being implemented, and the > Nashorn classes themselves. This can get tricky if you're implementing > multiple interfaces coming from multiple class loaders. Nashorn will choose > a class loader from among all involved classes' and interfaces' class > loaders that can see all the classes (the "maximum visibility class > loader") by probing Class.forName from one loader with a name of a class > from another loader and seeing if it resolves to the same class. If it > finds one, it uses that as the parent loader for the adapter's loader. If > it can't find one, you get a TypeError at runtime. You know I have a fun > job when some days I wake up thinking "I need to write an algorithm for > finding a maximum in a lattice of ClassLoader objects partially ordered by > can-see-classes-in-the-other relation". > > On Feb 6, 2015, at 10:05 AM, Christopher Brown < > christopherbrown06 at gmail.com> wrote: > > > Hello, > > > > Is it possible to use the Java.type() then the Java.extend() syntax > > described here: > > https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions > > > > ...with interface types loaded from a classloader other than the JRE > > classloader and the main application classloader. > > > > As a simple example, suppose in the main() method of an application, I > > create a URL classloader to load arbitrary JAR files containing interface > > definitions, and then I create an instance of the Nashorn scripting > > engine. Is it possible to make these types visible to the scripting > > engine, such that I could (in a loaded script) use Java.type() then > > Java.extend() to create an implementation of such a dynamically-loaded > > interface, and return it from the script when invoking a given function? > > > > I'm guessing that it's not possible, because I've not seen this > documented > > anywhere. I would assume that it might be possible via the "context > > classloader" of the current thread, but I'd prefer not to rely on > > undocumented features (supposing that it's the case). The most flexible > > approach would be to pass a classloader (or a map/array of classloaders) > > into the binding, and pass it as a second parameter to the Java.type() > > function (especially if in a more complicated example, multiple URL > > classloaders were loaded and defined types with the same fully-qualified > > names). > > > > Additional question #1: would the implementation of the interface in > > Nashorn require that I implement default methods, or could they be > invoked > > in the script without defining them? > > > > Additional question #2: how should resources added to a binding, and more > > generally, resources used by a ScriptEngine instance, be cleaned up when > > the engine instance is no longer required? For example, if adding > > classloaders is (or can be made) possible, I can't see any way to > > explicitly "close" the script engine... I'm assuming the only way to > clean > > things up is to de-reference the engine and wait for it to be > > garbage-collected. > > > > Thanks, > > Christopher > > From sundararajan.athijegannathan at oracle.com Mon Feb 16 03:38:22 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Mon, 16 Feb 2015 09:08:22 +0530 Subject: Using Nashorn with interfaces loaded from custom classloaders In-Reply-To: References: Message-ID: <54E1662E.2010402@oracle.com> Actually, you don't need to modify the thread context class loader. You can just expose Java Class objects via a script "function" exposed to scripts. You can implement "script function" as a Java lambda. Then, you can use "static" property to make Java type object from it (as Attila mentioned in his email). Example: import javax.script.*; import java.util.function.*; class Main { public static void main(String[] ar) throws Exception { ScriptEngineManager m = new ScriptEngineManager(); ScriptEngine e = m.getEngineByName("nashorn"); e.put("JavaClass", (Function) s -> { try { // replace this whatever Class finding logic here // say, using your own class loader(s) based search return Class.forName(s); } catch (ClassNotFoundException cnfe) { throw new RuntimeException(cnfe); } }); // Using "static" property on Class object to make a // JS Java type object from a Java Class object e.eval("var System = JavaClass('java.lang.System').static"); // call static method on that Java type e.eval("System.out.println('hello world')"); } } This avoids any class loader setting or even changing existing API. -Sundar On Sunday 15 February 2015 08:16 PM, Christopher Brown wrote: > Hello, > > Setting the context classloader when instantiating the script engine, as > you suggested, solved my problem (note: the ScriptEngineManager had to be > instantiated before changing the context classloader, as otherwise the > "nashorn" engine couldn't be found). Here's the code: > > ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); > thread.setContextClassLoader(MyApiInterface.class.getClassLoader()); > ScriptEngine engine = > scriptEngineManager.getEngineByName("nashorn"); > thread.setContextClassLoader(contextClassLoader); > > Will this technique supported in the future (all foreseeable versions), or > is it an implementation side-effect that is subject to change? > > Following on from your reply, making Java.type(...) accept an actual Class > instance would be great. Also, a variant, such as: > > Java.type(className, classLoaderOrArrayOfClassLoaders) > > ...would be great. > > Thank you for your very helpful answer! > > -- > Christopher > > > On 11 February 2015 at 09:56, Attila Szegedi > wrote: > >> Java.type will only resolve names against script engine's "app loader" >> (which is whatever was the thread context loader at the time engine >> instance was created) and additionally from the path passed in as >> "-classpath" command line option (to get an engine with extra command line >> options programmatically you'll need to use NashornScriptEngineFactory >> class directly instead of only relying on javax.script.* APIs; actually you >> can pass explicit "app loader" with some of NashornScriptEngineFactory >> factory methods too). >> >> In absence of this, you can do the following: if you pass in a Class >> object representing your interface (let's call it ForeignInterface) into >> the runtime somehow (e.g. through Bindings): >> >> bindings.put("foreignInterfaceClass", ForeignInterface.class) >> >> then you can use "foreignInterfaceClass.static" to represent the static >> aspect of the type[1] in the script. Thereafter, >> >> var ForeignInterface = foreignInterfaceClass.static; >> var adapter = Java.extend(ForeignInterface ... >> >> should work, with the caveat that Nashorn's own classes must be visible >> through the class loader for ForeignInterface, as Nashorn will essentially >> be loading an adapter class that will have an "implements ForeignInterface" >> clause but it will also rely on some Nashorn internals in its bytecode, so >> it must be able to resolve symbolic bytecode references both to >> ForeignInterface and to some Nashorn classes. If your class loader has the >> extension class loader (which is where Nashorn lives) somewhere in its >> parent chain, you're good. Otherwise, if you have some more involved class >> loader topology, then I'm sorry to say that you're out of luck[2] :-( >> >> As for your additional questions: >> >> #1 you can decide to not implement all methods of the interface (in fact, >> you could choose to implement none of them :-) ). If the underlying script >> object provides no implementation for an invoked method, then interface >> default method is invoked if one is provided by the interface, otherwise >> java.lang.UnsupportedOperationException is thrown. >> >> #2 yes, javax.script has no explicit cleanup mechanism for script engines. >> It gets GC'd if it's unreachable. If you need resource cleanup tied to it >> not being reachable anymore, you'll need to use PhantomReference. >> >> HTH, >> Attila. >> >> --- >> [1] the one you would in Java simply call "ForeignInterface", except in >> Java it's not a reified object, but purely a lexical language construct. In >> Nashorn, static types are reified, and you can think of ".static" as being >> the inverse operation of ".class"; .class on a static type gives you a >> runtime type (java.lang.Class) object, while .static on a j.l.Class object >> gives you back the static type which is used as both the constructor >> function for the type and a namespace for static fields/properties/methods >> (just as in Java). This whole discussion about static types makes me want >> to extend the Java.extend so that it accepts either a static type or a >> runtime j.l.Class object in its arguments, though. >> >> [2] The truth is actually somewhat more complex; when Nashorn defines the >> adapter class, it does so in a small new class loader, and it needs to find >> a suitable parent for this class loader: one that sees the class being >> extended (if there's one), all the interface(s) being implemented, and the >> Nashorn classes themselves. This can get tricky if you're implementing >> multiple interfaces coming from multiple class loaders. Nashorn will choose >> a class loader from among all involved classes' and interfaces' class >> loaders that can see all the classes (the "maximum visibility class >> loader") by probing Class.forName from one loader with a name of a class >> from another loader and seeing if it resolves to the same class. If it >> finds one, it uses that as the parent loader for the adapter's loader. If >> it can't find one, you get a TypeError at runtime. You know I have a fun >> job when some days I wake up thinking "I need to write an algorithm for >> finding a maximum in a lattice of ClassLoader objects partially ordered by >> can-see-classes-in-the-other relation". >> >> On Feb 6, 2015, at 10:05 AM, Christopher Brown < >> christopherbrown06 at gmail.com> wrote: >> >>> Hello, >>> >>> Is it possible to use the Java.type() then the Java.extend() syntax >>> described here: >>> https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions >>> >>> ...with interface types loaded from a classloader other than the JRE >>> classloader and the main application classloader. >>> >>> As a simple example, suppose in the main() method of an application, I >>> create a URL classloader to load arbitrary JAR files containing interface >>> definitions, and then I create an instance of the Nashorn scripting >>> engine. Is it possible to make these types visible to the scripting >>> engine, such that I could (in a loaded script) use Java.type() then >>> Java.extend() to create an implementation of such a dynamically-loaded >>> interface, and return it from the script when invoking a given function? >>> >>> I'm guessing that it's not possible, because I've not seen this >> documented >>> anywhere. I would assume that it might be possible via the "context >>> classloader" of the current thread, but I'd prefer not to rely on >>> undocumented features (supposing that it's the case). The most flexible >>> approach would be to pass a classloader (or a map/array of classloaders) >>> into the binding, and pass it as a second parameter to the Java.type() >>> function (especially if in a more complicated example, multiple URL >>> classloaders were loaded and defined types with the same fully-qualified >>> names). >>> >>> Additional question #1: would the implementation of the interface in >>> Nashorn require that I implement default methods, or could they be >> invoked >>> in the script without defining them? >>> >>> Additional question #2: how should resources added to a binding, and more >>> generally, resources used by a ScriptEngine instance, be cleaned up when >>> the engine instance is no longer required? For example, if adding >>> classloaders is (or can be made) possible, I can't see any way to >>> explicitly "close" the script engine... I'm assuming the only way to >> clean >>> things up is to de-reference the engine and wait for it to be >>> garbage-collected. >>> >>> Thanks, >>> Christopher >> From christopherbrown06 at gmail.com Mon Feb 16 07:53:09 2015 From: christopherbrown06 at gmail.com (Christopher Brown) Date: Mon, 16 Feb 2015 08:53:09 +0100 Subject: How to extend a Java interface or class with overloaded methods using Nashorn? Message-ID: Hello, Maybe this is answered somewhere ; I tried looking here (maybe missed it though): https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions How should you provide a JavaScript implemention using Nashorn of a Java interface such as this: package baz; public interface Foo { void bar(); void bar(String s); void bar(Integer i); void bar(Object ... varargs); } Assuming that it's straightforward to load "Foo" using Java.type (or other approaches suggested in answer to my previous e-mail), how would I actually go about defining the implementation? var Foo = Java.type('baz.Foo'); var instance = new Foo { bar: new function(){ // how do I know which arguments were passed? // how do I define the other signatures? } }; I'm guessing that I can only define one "bar" function, is that right? Should I try and detect which variant was invoked by using the implicit "arguments" array, or should I define some formal parameters (and how would that map to values which defined as scalars in some cases, and collections in others)? If there's a Nashorn-specific way of defining specific signatures (there IS an example, "explicit method selection", with as cast to out["println(int)"], but that's not the direction I'm looking for), how can a JavaScript calling method select the intended overload? Thanks, Christopher From christopherbrown06 at gmail.com Tue Feb 17 21:57:41 2015 From: christopherbrown06 at gmail.com (Christopher Brown) Date: Tue, 17 Feb 2015 22:57:41 +0100 Subject: Using Nashorn with interfaces loaded from custom classloaders In-Reply-To: <54E1662E.2010402@oracle.com> References: <54E1662E.2010402@oracle.com> Message-ID: Hello Sundar, Your suggestion works too. Would it be the recommended (more future-proof) approach, as opposed to setting the context classloader when instantiating the ScriptEngine instance? I'm guessing that it is. Is there any way to make it even neater, by moving the ".static" logic from the JavaScript side into the "JavaClass" function, so that the JavaScript code can just invoke the JavaClass("className") function without needing to add ".static" after each usage (to avoid typing, and to avoid side effects when forgotten)? Thanks, Christopher On 16 February 2015 at 04:38, A. Sundararajan < sundararajan.athijegannathan at oracle.com> wrote: > Actually, you don't need to modify the thread context class loader. You > can just expose Java Class objects via a script "function" exposed to > scripts. You can implement "script function" as a Java lambda. Then, you > can use "static" property to make Java type object from it (as Attila > mentioned in his email). > > Example: > > import javax.script.*; > import java.util.function.*; > > class Main { > public static void main(String[] ar) throws Exception { > ScriptEngineManager m = new ScriptEngineManager(); > ScriptEngine e = m.getEngineByName("nashorn"); > > e.put("JavaClass", (Function) > s -> { > try { > // replace this whatever Class finding logic here > // say, using your own class loader(s) based search > return Class.forName(s); > } catch (ClassNotFoundException cnfe) { > throw new RuntimeException(cnfe); > } > }); > > // Using "static" property on Class object to make a > // JS Java type object from a Java Class object > e.eval("var System = JavaClass('java.lang.System').static"); > > // call static method on that Java type > e.eval("System.out.println('hello world')"); > } > } > > This avoids any class loader setting or even changing existing API. > > -Sundar > > > > On Sunday 15 February 2015 08:16 PM, Christopher Brown wrote: > >> Hello, >> >> Setting the context classloader when instantiating the script engine, as >> you suggested, solved my problem (note: the ScriptEngineManager had to be >> instantiated before changing the context classloader, as otherwise the >> "nashorn" engine couldn't be found). Here's the code: >> >> ScriptEngineManager scriptEngineManager = new >> ScriptEngineManager(); >> thread.setContextClassLoader(MyApiInterface.class. >> getClassLoader()); >> ScriptEngine engine = >> scriptEngineManager.getEngineByName("nashorn"); >> thread.setContextClassLoader(contextClassLoader); >> >> Will this technique supported in the future (all foreseeable versions), or >> is it an implementation side-effect that is subject to change? >> >> Following on from your reply, making Java.type(...) accept an actual Class >> instance would be great. Also, a variant, such as: >> >> Java.type(className, classLoaderOrArrayOfClassLoaders) >> >> ...would be great. >> >> Thank you for your very helpful answer! >> >> -- >> Christopher >> >> >> On 11 February 2015 at 09:56, Attila Szegedi >> wrote: >> >> Java.type will only resolve names against script engine's "app loader" >>> (which is whatever was the thread context loader at the time engine >>> instance was created) and additionally from the path passed in as >>> "-classpath" command line option (to get an engine with extra command >>> line >>> options programmatically you'll need to use NashornScriptEngineFactory >>> class directly instead of only relying on javax.script.* APIs; actually >>> you >>> can pass explicit "app loader" with some of NashornScriptEngineFactory >>> factory methods too). >>> >>> In absence of this, you can do the following: if you pass in a Class >>> object representing your interface (let's call it ForeignInterface) into >>> the runtime somehow (e.g. through Bindings): >>> >>> bindings.put("foreignInterfaceClass", ForeignInterface.class) >>> >>> then you can use "foreignInterfaceClass.static" to represent the static >>> aspect of the type[1] in the script. Thereafter, >>> >>> var ForeignInterface = foreignInterfaceClass.static; >>> var adapter = Java.extend(ForeignInterface ... >>> >>> should work, with the caveat that Nashorn's own classes must be visible >>> through the class loader for ForeignInterface, as Nashorn will >>> essentially >>> be loading an adapter class that will have an "implements >>> ForeignInterface" >>> clause but it will also rely on some Nashorn internals in its bytecode, >>> so >>> it must be able to resolve symbolic bytecode references both to >>> ForeignInterface and to some Nashorn classes. If your class loader has >>> the >>> extension class loader (which is where Nashorn lives) somewhere in its >>> parent chain, you're good. Otherwise, if you have some more involved >>> class >>> loader topology, then I'm sorry to say that you're out of luck[2] :-( >>> >>> As for your additional questions: >>> >>> #1 you can decide to not implement all methods of the interface (in fact, >>> you could choose to implement none of them :-) ). If the underlying >>> script >>> object provides no implementation for an invoked method, then interface >>> default method is invoked if one is provided by the interface, otherwise >>> java.lang.UnsupportedOperationException is thrown. >>> >>> #2 yes, javax.script has no explicit cleanup mechanism for script >>> engines. >>> It gets GC'd if it's unreachable. If you need resource cleanup tied to it >>> not being reachable anymore, you'll need to use PhantomReference. >>> >>> HTH, >>> Attila. >>> >>> --- >>> [1] the one you would in Java simply call "ForeignInterface", except in >>> Java it's not a reified object, but purely a lexical language construct. >>> In >>> Nashorn, static types are reified, and you can think of ".static" as >>> being >>> the inverse operation of ".class"; .class on a static type gives you a >>> runtime type (java.lang.Class) object, while .static on a j.l.Class >>> object >>> gives you back the static type which is used as both the constructor >>> function for the type and a namespace for static >>> fields/properties/methods >>> (just as in Java). This whole discussion about static types makes me want >>> to extend the Java.extend so that it accepts either a static type or a >>> runtime j.l.Class object in its arguments, though. >>> >>> [2] The truth is actually somewhat more complex; when Nashorn defines the >>> adapter class, it does so in a small new class loader, and it needs to >>> find >>> a suitable parent for this class loader: one that sees the class being >>> extended (if there's one), all the interface(s) being implemented, and >>> the >>> Nashorn classes themselves. This can get tricky if you're implementing >>> multiple interfaces coming from multiple class loaders. Nashorn will >>> choose >>> a class loader from among all involved classes' and interfaces' class >>> loaders that can see all the classes (the "maximum visibility class >>> loader") by probing Class.forName from one loader with a name of a class >>> from another loader and seeing if it resolves to the same class. If it >>> finds one, it uses that as the parent loader for the adapter's loader. If >>> it can't find one, you get a TypeError at runtime. You know I have a fun >>> job when some days I wake up thinking "I need to write an algorithm for >>> finding a maximum in a lattice of ClassLoader objects partially ordered >>> by >>> can-see-classes-in-the-other relation". >>> >>> On Feb 6, 2015, at 10:05 AM, Christopher Brown < >>> christopherbrown06 at gmail.com> wrote: >>> >>> Hello, >>>> >>>> Is it possible to use the Java.type() then the Java.extend() syntax >>>> described here: >>>> https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions >>>> >>>> ...with interface types loaded from a classloader other than the JRE >>>> classloader and the main application classloader. >>>> >>>> As a simple example, suppose in the main() method of an application, I >>>> create a URL classloader to load arbitrary JAR files containing >>>> interface >>>> definitions, and then I create an instance of the Nashorn scripting >>>> engine. Is it possible to make these types visible to the scripting >>>> engine, such that I could (in a loaded script) use Java.type() then >>>> Java.extend() to create an implementation of such a dynamically-loaded >>>> interface, and return it from the script when invoking a given function? >>>> >>>> I'm guessing that it's not possible, because I've not seen this >>>> >>> documented >>> >>>> anywhere. I would assume that it might be possible via the "context >>>> classloader" of the current thread, but I'd prefer not to rely on >>>> undocumented features (supposing that it's the case). The most flexible >>>> approach would be to pass a classloader (or a map/array of classloaders) >>>> into the binding, and pass it as a second parameter to the Java.type() >>>> function (especially if in a more complicated example, multiple URL >>>> classloaders were loaded and defined types with the same fully-qualified >>>> names). >>>> >>>> Additional question #1: would the implementation of the interface in >>>> Nashorn require that I implement default methods, or could they be >>>> >>> invoked >>> >>>> in the script without defining them? >>>> >>>> Additional question #2: how should resources added to a binding, and >>>> more >>>> generally, resources used by a ScriptEngine instance, be cleaned up when >>>> the engine instance is no longer required? For example, if adding >>>> classloaders is (or can be made) possible, I can't see any way to >>>> explicitly "close" the script engine... I'm assuming the only way to >>>> >>> clean >>> >>>> things up is to de-reference the engine and wait for it to be >>>> garbage-collected. >>>> >>>> Thanks, >>>> Christopher >>>> >>> >>> > From sundararajan.athijegannathan at oracle.com Wed Feb 18 03:49:15 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Wed, 18 Feb 2015 09:19:15 +0530 Subject: Using Nashorn with interfaces loaded from custom classloaders In-Reply-To: References: <54E1662E.2010402@oracle.com> Message-ID: <54E40BBB.3020806@oracle.com> Hi Christopher, This is definitely a future-proof solution. On moving ".static" out to Java code (inside "JavaClass" function): ".static" creates an Nashorn internal class StaticClass instance. Since you can't refer to it from Java code (it is from a package that is listed in "sensitive packages" list in java.security), it is important to do ".static" from script code. You can of source introduce a script function that you "eval" as first script. Something like: e.eval("function JavaType(name) { return JavaClass(name).static; }"); // where JavaClass is that function exposed from your java code. You can call JavaType from other scripts. Thanks -Sundar Christopher Brown wrote: > Hello Sundar, > > Your suggestion works too. Would it be the recommended (more > future-proof) approach, as opposed to setting the context classloader > when instantiating the ScriptEngine instance? I'm guessing that it is. > > Is there any way to make it even neater, by moving the ".static" logic > from the JavaScript side into the "JavaClass" function, so that the > JavaScript code can just invoke the JavaClass("className") function > without needing to add ".static" after each usage (to avoid typing, > and to avoid side effects when forgotten)? > > Thanks, > Christopher > > > On 16 February 2015 at 04:38, A. Sundararajan > > wrote: > > Actually, you don't need to modify the thread context class > loader. You can just expose Java Class objects via a script > "function" exposed to scripts. You can implement "script function" > as a Java lambda. Then, you can use "static" property to make Java > type object from it (as Attila mentioned in his email). > > Example: > > import javax.script.*; > import java.util.function.*; > > class Main { > public static void main(String[] ar) throws Exception { > ScriptEngineManager m = new ScriptEngineManager(); > ScriptEngine e = m.getEngineByName("nashorn"); > > e.put("JavaClass", (Function) > s -> { > try { > // replace this whatever Class finding logic here > // say, using your own class loader(s) based search > return Class.forName(s); > } catch (ClassNotFoundException cnfe) { > throw new RuntimeException(cnfe); > } > }); > > // Using "static" property on Class object to make a > // JS Java type object from a Java Class object > e.eval("var System = JavaClass('java.lang.System').static"); > > // call static method on that Java type > e.eval("System.out.println('hello world')"); > } > } > > This avoids any class loader setting or even changing existing API. > > -Sundar > > > > On Sunday 15 February 2015 08:16 PM, Christopher Brown wrote: > > Hello, > > Setting the context classloader when instantiating the script > engine, as > you suggested, solved my problem (note: the > ScriptEngineManager had to be > instantiated before changing the context classloader, as > otherwise the > "nashorn" engine couldn't be found). Here's the code: > > ScriptEngineManager scriptEngineManager = new > ScriptEngineManager(); > > thread.setContextClassLoader(MyApiInterface.class.getClassLoader()); > ScriptEngine engine = > scriptEngineManager.getEngineByName("nashorn"); > thread.setContextClassLoader(contextClassLoader); > > Will this technique supported in the future (all foreseeable > versions), or > is it an implementation side-effect that is subject to change? > > Following on from your reply, making Java.type(...) accept an > actual Class > instance would be great. Also, a variant, such as: > > Java.type(className, classLoaderOrArrayOfClassLoaders) > > ...would be great. > > Thank you for your very helpful answer! > > -- > Christopher > > > On 11 February 2015 at 09:56, Attila Szegedi > > > wrote: > > Java.type will only resolve names against script engine's > "app loader" > (which is whatever was the thread context loader at the > time engine > instance was created) and additionally from the path > passed in as > "-classpath" command line option (to get an engine with > extra command line > options programmatically you'll need to use > NashornScriptEngineFactory > class directly instead of only relying on javax.script.* > APIs; actually you > can pass explicit "app loader" with some of > NashornScriptEngineFactory > factory methods too). > > In absence of this, you can do the following: if you pass > in a Class > object representing your interface (let's call it > ForeignInterface) into > the runtime somehow (e.g. through Bindings): > > bindings.put("foreignInterfaceClass", > ForeignInterface.class) > > then you can use "foreignInterfaceClass.static" to > represent the static > aspect of the type[1] in the script. Thereafter, > > var ForeignInterface = foreignInterfaceClass.static; > var adapter = Java.extend(ForeignInterface ... > > should work, with the caveat that Nashorn's own classes > must be visible > through the class loader for ForeignInterface, as Nashorn > will essentially > be loading an adapter class that will have an "implements > ForeignInterface" > clause but it will also rely on some Nashorn internals in > its bytecode, so > it must be able to resolve symbolic bytecode references > both to > ForeignInterface and to some Nashorn classes. If your > class loader has the > extension class loader (which is where Nashorn lives) > somewhere in its > parent chain, you're good. Otherwise, if you have some > more involved class > loader topology, then I'm sorry to say that you're out of > luck[2] :-( > > As for your additional questions: > > #1 you can decide to not implement all methods of the > interface (in fact, > you could choose to implement none of them :-) ). If the > underlying script > object provides no implementation for an invoked method, > then interface > default method is invoked if one is provided by the > interface, otherwise > java.lang.UnsupportedOperationException is thrown. > > #2 yes, javax.script has no explicit cleanup mechanism for > script engines. > It gets GC'd if it's unreachable. If you need resource > cleanup tied to it > not being reachable anymore, you'll need to use > PhantomReference. > > HTH, > Attila. > > --- > [1] the one you would in Java simply call > "ForeignInterface", except in > Java it's not a reified object, but purely a lexical > language construct. In > Nashorn, static types are reified, and you can think of > ".static" as being > the inverse operation of ".class"; .class on a static type > gives you a > runtime type (java.lang.Class) object, while .static on a > j.l.Class object > gives you back the static type which is used as both the > constructor > function for the type and a namespace for static > fields/properties/methods > (just as in Java). This whole discussion about static > types makes me want > to extend the Java.extend so that it accepts either a > static type or a > runtime j.l.Class object in its arguments, though. > > [2] The truth is actually somewhat more complex; when > Nashorn defines the > adapter class, it does so in a small new class loader, and > it needs to find > a suitable parent for this class loader: one that sees the > class being > extended (if there's one), all the interface(s) being > implemented, and the > Nashorn classes themselves. This can get tricky if you're > implementing > multiple interfaces coming from multiple class loaders. > Nashorn will choose > a class loader from among all involved classes' and > interfaces' class > loaders that can see all the classes (the "maximum > visibility class > loader") by probing Class.forName from one loader with a > name of a class > from another loader and seeing if it resolves to the same > class. If it > finds one, it uses that as the parent loader for the > adapter's loader. If > it can't find one, you get a TypeError at runtime. You > know I have a fun > job when some days I wake up thinking "I need to write an > algorithm for > finding a maximum in a lattice of ClassLoader objects > partially ordered by > can-see-classes-in-the-other relation". > > On Feb 6, 2015, at 10:05 AM, Christopher Brown < > christopherbrown06 at gmail.com > > wrote: > > Hello, > > Is it possible to use the Java.type() then the > Java.extend() syntax > described here: > https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions > > ...with interface types loaded from a classloader > other than the JRE > classloader and the main application classloader. > > As a simple example, suppose in the main() method of > an application, I > create a URL classloader to load arbitrary JAR files > containing interface > definitions, and then I create an instance of the > Nashorn scripting > engine. Is it possible to make these types visible to > the scripting > engine, such that I could (in a loaded script) use > Java.type() then > Java.extend() to create an implementation of such a > dynamically-loaded > interface, and return it from the script when invoking > a given function? > > I'm guessing that it's not possible, because I've not > seen this > > documented > > anywhere. I would assume that it might be possible > via the "context > classloader" of the current thread, but I'd prefer not > to rely on > undocumented features (supposing that it's the case). > The most flexible > approach would be to pass a classloader (or a > map/array of classloaders) > into the binding, and pass it as a second parameter to > the Java.type() > function (especially if in a more complicated example, > multiple URL > classloaders were loaded and defined types with the > same fully-qualified > names). > > Additional question #1: would the implementation of > the interface in > Nashorn require that I implement default methods, or > could they be > > invoked > > in the script without defining them? > > Additional question #2: how should resources added to > a binding, and more > generally, resources used by a ScriptEngine instance, > be cleaned up when > the engine instance is no longer required? For > example, if adding > classloaders is (or can be made) possible, I can't see > any way to > explicitly "close" the script engine... I'm assuming > the only way to > > clean > > things up is to de-reference the engine and wait for > it to be > garbage-collected. > > Thanks, > Christopher > > > > From timvolpe at gmail.com Wed Feb 18 09:40:13 2015 From: timvolpe at gmail.com (Tim Fox) Date: Wed, 18 Feb 2015 09:40:13 +0000 Subject: How to set correct fileName for exceptions thrown from a function in a Function object Message-ID: <54E45DFD.4030607@gmail.com> Hi all, I'm currently using a CommonJS/npm modules require implementation (npm-jvm) with Nashorn. Roughly, the way it works (and I'm sure you're already familiar with this technique) is it takes the JavaScript module and wraps it in a Function object: var body = readScriptAsText(); var args = ['exports', 'module', 'require', '__filename', '__dirname']; var func = new Function(args, body); func.apply(module, [module.exports, module, module.require, module.filename, dir]); // Execute it - this works fine Now let's say the actual module (foomodule.js) we are loading contains this: module.exports = function() { var num = 234; num.substr(1, 1); // Will throw TypeError here } I.e. it simply exports a function, which will throw a TypeError when it's executed. When the exported function is executed it does indeed throw a TypeError: var f = require("foomodule"); f(); // Throws TypeError Unfortunately the fileName field of the TypeError is set to "" not to "foomodule.js", which is unfriendly for the user. This is understandable as the Function object which wraps the module doesn't know about "foomodule.js". So.. my question is.. how do I tell the Function object that the "filename" it should use when exceptions are thrown from it is "foomodule.js"? I have tried the following and none work: var func = new Function(args, body); func.name = "foomodule.js"; func.fileName = "foomodule.js"; func.displayName = "foomodule.js"; Any insights would be greatly appreciated. From timvolpe at gmail.com Wed Feb 18 10:00:39 2015 From: timvolpe at gmail.com (Tim Fox) Date: Wed, 18 Feb 2015 10:00:39 +0000 Subject: How to set correct fileName for exceptions thrown from a function in a Function object In-Reply-To: <54E45DFD.4030607@gmail.com> References: <54E45DFD.4030607@gmail.com> Message-ID: <54E462C7.5040402@gmail.com> I've added a simple reproducer that you can run in the repl: https://gist.github.com/purplefox/b03a2a6263c26e3206da Another observation is that line number is reported as 6, when it should be 5 (assuming the first line is line 1 which is normal convention afaik) On 18/02/15 09:40, Tim Fox wrote: > Hi all, > > I'm currently using a CommonJS/npm modules require implementation > (npm-jvm) with Nashorn. > > Roughly, the way it works (and I'm sure you're already familiar with > this technique) is it takes the JavaScript module and wraps it in a > Function object: > > var body = readScriptAsText(); > var args = ['exports', 'module', 'require', '__filename', '__dirname']; > var func = new Function(args, body); > func.apply(module, [module.exports, module, module.require, > module.filename, dir]); // Execute it - this works fine > > Now let's say the actual module (foomodule.js) we are loading contains > this: > > module.exports = function() { > var num = 234; > num.substr(1, 1); // Will throw TypeError here > } > > I.e. it simply exports a function, which will throw a TypeError when > it's executed. > > When the exported function is executed it does indeed throw a TypeError: > > var f = require("foomodule"); > > f(); // Throws TypeError > > Unfortunately the fileName field of the TypeError is set to > "" not to "foomodule.js", which is unfriendly for the user. > > This is understandable as the Function object which wraps the module > doesn't know about "foomodule.js". > > So.. my question is.. how do I tell the Function object that the > "filename" it should use when exceptions are thrown from it is > "foomodule.js"? > > I have tried the following and none work: > > var func = new Function(args, body); > func.name = "foomodule.js"; > func.fileName = "foomodule.js"; > func.displayName = "foomodule.js"; > > Any insights would be greatly appreciated. > > > > From sundararajan.athijegannathan at oracle.com Wed Feb 18 10:11:47 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Wed, 18 Feb 2015 15:41:47 +0530 Subject: How to set correct fileName for exceptions thrown from a function in a Function object In-Reply-To: <54E462C7.5040402@gmail.com> References: <54E45DFD.4030607@gmail.com> <54E462C7.5040402@gmail.com> Message-ID: <54E46563.8040707@oracle.com> you can use 1) "load" from object - object with name and script properties. 2) or use 'eval' naming // #sourceURL comment as mentioned here: http://mail.openjdk.java.net/pipermail/nashorn-dev/2014-July/003174.html Can code for body of module function be something like "eval(readScriptAsText() + "\n// #sourceURL=" + name)" ? Hope this helps, -Sundar On Wednesday 18 February 2015 03:30 PM, Tim Fox wrote: > I've added a simple reproducer that you can run in the repl: > > https://gist.github.com/purplefox/b03a2a6263c26e3206da > > Another observation is that line number is reported as 6, when it > should be 5 (assuming the first line is line 1 which is normal > convention afaik) > > On 18/02/15 09:40, Tim Fox wrote: >> Hi all, >> >> I'm currently using a CommonJS/npm modules require implementation >> (npm-jvm) with Nashorn. >> >> Roughly, the way it works (and I'm sure you're already familiar with >> this technique) is it takes the JavaScript module and wraps it in a >> Function object: >> >> var body = readScriptAsText(); >> var args = ['exports', 'module', 'require', '__filename', >> '__dirname']; >> var func = new Function(args, body); >> func.apply(module, [module.exports, module, module.require, >> module.filename, dir]); // Execute it - this works fine >> >> Now let's say the actual module (foomodule.js) we are loading >> contains this: >> >> module.exports = function() { >> var num = 234; >> num.substr(1, 1); // Will throw TypeError here >> } >> >> I.e. it simply exports a function, which will throw a TypeError when >> it's executed. >> >> When the exported function is executed it does indeed throw a TypeError: >> >> var f = require("foomodule"); >> >> f(); // Throws TypeError >> >> Unfortunately the fileName field of the TypeError is set to >> "" not to "foomodule.js", which is unfriendly for the user. >> >> This is understandable as the Function object which wraps the module >> doesn't know about "foomodule.js". >> >> So.. my question is.. how do I tell the Function object that the >> "filename" it should use when exceptions are thrown from it is >> "foomodule.js"? >> >> I have tried the following and none work: >> >> var func = new Function(args, body); >> func.name = "foomodule.js"; >> func.fileName = "foomodule.js"; >> func.displayName = "foomodule.js"; >> >> Any insights would be greatly appreciated. >> >> >> >> > From timvolpe at gmail.com Wed Feb 18 12:44:02 2015 From: timvolpe at gmail.com (Tim Fox) Date: Wed, 18 Feb 2015 12:44:02 +0000 Subject: How to set correct fileName for exceptions thrown from a function in a Function object In-Reply-To: <54E46563.8040707@oracle.com> References: <54E45DFD.4030607@gmail.com> <54E462C7.5040402@gmail.com> <54E46563.8040707@oracle.com> Message-ID: <54E48912.1030308@gmail.com> Hi Sundar, I tried the sourceURL trick: https://gist.github.com/purplefox/60619067006c3cc3eaee But it doesn't seem to work. I suspect because the parsing of the eval fails before it gets to the last line (?) :( I'm going to give a go with load()... On 18/02/15 10:11, A. Sundararajan wrote: > you can use > > 1) "load" from object - object with name and script properties. > > 2) or use 'eval' naming // #sourceURL comment > > as mentioned here: > > http://mail.openjdk.java.net/pipermail/nashorn-dev/2014-July/003174.html > > Can code for body of module function be something like > "eval(readScriptAsText() + "\n// #sourceURL=" + name)" ? > > Hope this helps, > -Sundar > > On Wednesday 18 February 2015 03:30 PM, Tim Fox wrote: >> I've added a simple reproducer that you can run in the repl: >> >> https://gist.github.com/purplefox/b03a2a6263c26e3206da >> >> Another observation is that line number is reported as 6, when it >> should be 5 (assuming the first line is line 1 which is normal >> convention afaik) >> >> On 18/02/15 09:40, Tim Fox wrote: >>> Hi all, >>> >>> I'm currently using a CommonJS/npm modules require implementation >>> (npm-jvm) with Nashorn. >>> >>> Roughly, the way it works (and I'm sure you're already familiar with >>> this technique) is it takes the JavaScript module and wraps it in a >>> Function object: >>> >>> var body = readScriptAsText(); >>> var args = ['exports', 'module', 'require', '__filename', >>> '__dirname']; >>> var func = new Function(args, body); >>> func.apply(module, [module.exports, module, module.require, >>> module.filename, dir]); // Execute it - this works fine >>> >>> Now let's say the actual module (foomodule.js) we are loading >>> contains this: >>> >>> module.exports = function() { >>> var num = 234; >>> num.substr(1, 1); // Will throw TypeError here >>> } >>> >>> I.e. it simply exports a function, which will throw a TypeError when >>> it's executed. >>> >>> When the exported function is executed it does indeed throw a >>> TypeError: >>> >>> var f = require("foomodule"); >>> >>> f(); // Throws TypeError >>> >>> Unfortunately the fileName field of the TypeError is set to >>> "" not to "foomodule.js", which is unfriendly for the user. >>> >>> This is understandable as the Function object which wraps the module >>> doesn't know about "foomodule.js". >>> >>> So.. my question is.. how do I tell the Function object that the >>> "filename" it should use when exceptions are thrown from it is >>> "foomodule.js"? >>> >>> I have tried the following and none work: >>> >>> var func = new Function(args, body); >>> func.name = "foomodule.js"; >>> func.fileName = "foomodule.js"; >>> func.displayName = "foomodule.js"; >>> >>> Any insights would be greatly appreciated. >>> >>> >>> >>> >> > From sundararajan.athijegannathan at oracle.com Wed Feb 18 13:13:01 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Wed, 18 Feb 2015 18:43:01 +0530 Subject: How to set correct fileName for exceptions thrown from a function in a Function object In-Reply-To: <54E48912.1030308@gmail.com> References: <54E45DFD.4030607@gmail.com> <54E462C7.5040402@gmail.com> <54E46563.8040707@oracle.com> <54E48912.1030308@gmail.com> Message-ID: <54E48FDD.8070504@oracle.com> Hi Tim, It was added in 8u20 if I recall right. jjs -version nashorn 1.8.0_40 jjs> jjs> eval("f() //# sourceURL=t.js") t.js:1 ReferenceError: "f" is not defined jjs> eval("g() //@ sourceURL=g.js") g.js:1 ReferenceError: "g" is not defined I think your file has "// #sourceURL=wibble.js". Please try changing it as "//# sourceFile=wibble.js" See also: https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Debug_eval_sources -Sundar On Wednesday 18 February 2015 06:14 PM, Tim Fox wrote: > Hi Sundar, > > I tried the sourceURL trick: > > https://gist.github.com/purplefox/60619067006c3cc3eaee > > But it doesn't seem to work. I suspect because the parsing of the eval > fails before it gets to the last line (?) :( > > I'm going to give a go with load()... > > On 18/02/15 10:11, A. Sundararajan wrote: >> you can use >> >> 1) "load" from object - object with name and script properties. >> >> 2) or use 'eval' naming // #sourceURL comment >> >> as mentioned here: >> >> http://mail.openjdk.java.net/pipermail/nashorn-dev/2014-July/003174.html >> >> Can code for body of module function be something like >> "eval(readScriptAsText() + "\n// #sourceURL=" + name)" ? >> >> Hope this helps, >> -Sundar >> >> On Wednesday 18 February 2015 03:30 PM, Tim Fox wrote: >>> I've added a simple reproducer that you can run in the repl: >>> >>> https://gist.github.com/purplefox/b03a2a6263c26e3206da >>> >>> Another observation is that line number is reported as 6, when it >>> should be 5 (assuming the first line is line 1 which is normal >>> convention afaik) >>> >>> On 18/02/15 09:40, Tim Fox wrote: >>>> Hi all, >>>> >>>> I'm currently using a CommonJS/npm modules require implementation >>>> (npm-jvm) with Nashorn. >>>> >>>> Roughly, the way it works (and I'm sure you're already familiar >>>> with this technique) is it takes the JavaScript module and wraps it >>>> in a Function object: >>>> >>>> var body = readScriptAsText(); >>>> var args = ['exports', 'module', 'require', '__filename', >>>> '__dirname']; >>>> var func = new Function(args, body); >>>> func.apply(module, [module.exports, module, module.require, >>>> module.filename, dir]); // Execute it - this works fine >>>> >>>> Now let's say the actual module (foomodule.js) we are loading >>>> contains this: >>>> >>>> module.exports = function() { >>>> var num = 234; >>>> num.substr(1, 1); // Will throw TypeError here >>>> } >>>> >>>> I.e. it simply exports a function, which will throw a TypeError >>>> when it's executed. >>>> >>>> When the exported function is executed it does indeed throw a >>>> TypeError: >>>> >>>> var f = require("foomodule"); >>>> >>>> f(); // Throws TypeError >>>> >>>> Unfortunately the fileName field of the TypeError is set to >>>> "" not to "foomodule.js", which is unfriendly for the user. >>>> >>>> This is understandable as the Function object which wraps the >>>> module doesn't know about "foomodule.js". >>>> >>>> So.. my question is.. how do I tell the Function object that the >>>> "filename" it should use when exceptions are thrown from it is >>>> "foomodule.js"? >>>> >>>> I have tried the following and none work: >>>> >>>> var func = new Function(args, body); >>>> func.name = "foomodule.js"; >>>> func.fileName = "foomodule.js"; >>>> func.displayName = "foomodule.js"; >>>> >>>> Any insights would be greatly appreciated. >>>> >>>> >>>> >>>> >>> >> > From timvolpe at gmail.com Wed Feb 18 13:28:07 2015 From: timvolpe at gmail.com (Tim Fox) Date: Wed, 18 Feb 2015 13:28:07 +0000 Subject: How to set correct fileName for exceptions thrown from a function in a Function object In-Reply-To: <54E48FDD.8070504@oracle.com> References: <54E45DFD.4030607@gmail.com> <54E462C7.5040402@gmail.com> <54E46563.8040707@oracle.com> <54E48912.1030308@gmail.com> <54E48FDD.8070504@oracle.com> Message-ID: <54E49367.7000103@gmail.com> On 18/02/15 13:13, A. Sundararajan wrote: > > Hi Tim, > > It was added in 8u20 if I recall right. > > jjs -version > nashorn 1.8.0_40 > jjs> > jjs> eval("f() //# sourceURL=t.js") > t.js:1 ReferenceError: "f" is not defined > jjs> eval("g() //@ sourceURL=g.js") > g.js:1 ReferenceError: "g" is not defined > > I think your file has "// #sourceURL=wibble.js". Please try changing > it as "//# sourceFile=wibble.js" Ok, I am confused now... I have tried both #sourceURL (which most of the google hits say to use) and #sourceFile and neither seem to work ;) I've also tried @sourceURL which some other links say to use. (Yay for consistency ;) ) Nothing seems to work so far. I am using nashorn 1.8.0_25 which is the latest version in the production Oracle JDK afaict. Do I have to use OpenJDK to get these changes? I don't think this will be an option as most of users use the Oracle JDK. > > See also: > https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Debug_eval_sources > > -Sundar > > On Wednesday 18 February 2015 06:14 PM, Tim Fox wrote: >> Hi Sundar, >> >> I tried the sourceURL trick: >> >> https://gist.github.com/purplefox/60619067006c3cc3eaee >> >> But it doesn't seem to work. I suspect because the parsing of the >> eval fails before it gets to the last line (?) :( >> >> I'm going to give a go with load()... >> >> On 18/02/15 10:11, A. Sundararajan wrote: >>> you can use >>> >>> 1) "load" from object - object with name and script properties. >>> >>> 2) or use 'eval' naming // #sourceURL comment >>> >>> as mentioned here: >>> >>> http://mail.openjdk.java.net/pipermail/nashorn-dev/2014-July/003174.html >>> >>> >>> Can code for body of module function be something like >>> "eval(readScriptAsText() + "\n// #sourceURL=" + name)" ? >>> >>> Hope this helps, >>> -Sundar >>> >>> On Wednesday 18 February 2015 03:30 PM, Tim Fox wrote: >>>> I've added a simple reproducer that you can run in the repl: >>>> >>>> https://gist.github.com/purplefox/b03a2a6263c26e3206da >>>> >>>> Another observation is that line number is reported as 6, when it >>>> should be 5 (assuming the first line is line 1 which is normal >>>> convention afaik) >>>> >>>> On 18/02/15 09:40, Tim Fox wrote: >>>>> Hi all, >>>>> >>>>> I'm currently using a CommonJS/npm modules require implementation >>>>> (npm-jvm) with Nashorn. >>>>> >>>>> Roughly, the way it works (and I'm sure you're already familiar >>>>> with this technique) is it takes the JavaScript module and wraps >>>>> it in a Function object: >>>>> >>>>> var body = readScriptAsText(); >>>>> var args = ['exports', 'module', 'require', '__filename', >>>>> '__dirname']; >>>>> var func = new Function(args, body); >>>>> func.apply(module, [module.exports, module, module.require, >>>>> module.filename, dir]); // Execute it - this works fine >>>>> >>>>> Now let's say the actual module (foomodule.js) we are loading >>>>> contains this: >>>>> >>>>> module.exports = function() { >>>>> var num = 234; >>>>> num.substr(1, 1); // Will throw TypeError here >>>>> } >>>>> >>>>> I.e. it simply exports a function, which will throw a TypeError >>>>> when it's executed. >>>>> >>>>> When the exported function is executed it does indeed throw a >>>>> TypeError: >>>>> >>>>> var f = require("foomodule"); >>>>> >>>>> f(); // Throws TypeError >>>>> >>>>> Unfortunately the fileName field of the TypeError is set to >>>>> "" not to "foomodule.js", which is unfriendly for the user. >>>>> >>>>> This is understandable as the Function object which wraps the >>>>> module doesn't know about "foomodule.js". >>>>> >>>>> So.. my question is.. how do I tell the Function object that the >>>>> "filename" it should use when exceptions are thrown from it is >>>>> "foomodule.js"? >>>>> >>>>> I have tried the following and none work: >>>>> >>>>> var func = new Function(args, body); >>>>> func.name = "foomodule.js"; >>>>> func.fileName = "foomodule.js"; >>>>> func.displayName = "foomodule.js"; >>>>> >>>>> Any insights would be greatly appreciated. >>>>> >>>>> >>>>> >>>>> >>>> >>> >> > From sundararajan.athijegannathan at oracle.com Wed Feb 18 13:33:25 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Wed, 18 Feb 2015 19:03:25 +0530 Subject: How to set correct fileName for exceptions thrown from a function in a Function object In-Reply-To: <54E49367.7000103@gmail.com> References: <54E45DFD.4030607@gmail.com> <54E462C7.5040402@gmail.com> <54E46563.8040707@oracle.com> <54E48912.1030308@gmail.com> <54E48FDD.8070504@oracle.com> <54E49367.7000103@gmail.com> Message-ID: <54E494A5.8060901@oracle.com> So, did you fix "// #sourceURL" to //# sourceURL" ? Note on the whitespace: no whitespace between '//' and '#' and single whitespace after '#' ? Release notes page here says the fix is in 8u20. http://www.oracle.com/technetwork/java/javase/2col/8u20-bugfixes-2257730.html. Bug id is http://bugs.java.com/view_bug.do?bug_id=8032068 -Sundar On Wednesday 18 February 2015 06:58 PM, Tim Fox wrote: > On 18/02/15 13:13, A. Sundararajan wrote: >> >> Hi Tim, >> >> It was added in 8u20 if I recall right. >> >> jjs -version >> nashorn 1.8.0_40 >> jjs> >> jjs> eval("f() //# sourceURL=t.js") >> t.js:1 ReferenceError: "f" is not defined >> jjs> eval("g() //@ sourceURL=g.js") >> g.js:1 ReferenceError: "g" is not defined >> >> I think your file has "// #sourceURL=wibble.js". Please try changing >> it as "//# sourceFile=wibble.js" > > Ok, I am confused now... I have tried both #sourceURL (which most of > the google hits say to use) and #sourceFile and neither seem to work ;) > > I've also tried @sourceURL which some other links say to use. (Yay for > consistency ;) ) > > Nothing seems to work so far. > > I am using nashorn 1.8.0_25 which is the latest version in the > production Oracle JDK afaict. Do I have to use OpenJDK to get these > changes? I don't think this will be an option as most of users use the > Oracle JDK. > >> >> See also: >> https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Debug_eval_sources >> >> -Sundar >> >> On Wednesday 18 February 2015 06:14 PM, Tim Fox wrote: >>> Hi Sundar, >>> >>> I tried the sourceURL trick: >>> >>> https://gist.github.com/purplefox/60619067006c3cc3eaee >>> >>> But it doesn't seem to work. I suspect because the parsing of the >>> eval fails before it gets to the last line (?) :( >>> >>> I'm going to give a go with load()... >>> >>> On 18/02/15 10:11, A. Sundararajan wrote: >>>> you can use >>>> >>>> 1) "load" from object - object with name and script properties. >>>> >>>> 2) or use 'eval' naming // #sourceURL comment >>>> >>>> as mentioned here: >>>> >>>> http://mail.openjdk.java.net/pipermail/nashorn-dev/2014-July/003174.html >>>> >>>> >>>> Can code for body of module function be something like >>>> "eval(readScriptAsText() + "\n// #sourceURL=" + name)" ? >>>> >>>> Hope this helps, >>>> -Sundar >>>> >>>> On Wednesday 18 February 2015 03:30 PM, Tim Fox wrote: >>>>> I've added a simple reproducer that you can run in the repl: >>>>> >>>>> https://gist.github.com/purplefox/b03a2a6263c26e3206da >>>>> >>>>> Another observation is that line number is reported as 6, when it >>>>> should be 5 (assuming the first line is line 1 which is normal >>>>> convention afaik) >>>>> >>>>> On 18/02/15 09:40, Tim Fox wrote: >>>>>> Hi all, >>>>>> >>>>>> I'm currently using a CommonJS/npm modules require implementation >>>>>> (npm-jvm) with Nashorn. >>>>>> >>>>>> Roughly, the way it works (and I'm sure you're already familiar >>>>>> with this technique) is it takes the JavaScript module and wraps >>>>>> it in a Function object: >>>>>> >>>>>> var body = readScriptAsText(); >>>>>> var args = ['exports', 'module', 'require', '__filename', >>>>>> '__dirname']; >>>>>> var func = new Function(args, body); >>>>>> func.apply(module, [module.exports, module, module.require, >>>>>> module.filename, dir]); // Execute it - this works fine >>>>>> >>>>>> Now let's say the actual module (foomodule.js) we are loading >>>>>> contains this: >>>>>> >>>>>> module.exports = function() { >>>>>> var num = 234; >>>>>> num.substr(1, 1); // Will throw TypeError here >>>>>> } >>>>>> >>>>>> I.e. it simply exports a function, which will throw a TypeError >>>>>> when it's executed. >>>>>> >>>>>> When the exported function is executed it does indeed throw a >>>>>> TypeError: >>>>>> >>>>>> var f = require("foomodule"); >>>>>> >>>>>> f(); // Throws TypeError >>>>>> >>>>>> Unfortunately the fileName field of the TypeError is set to >>>>>> "" not to "foomodule.js", which is unfriendly for the >>>>>> user. >>>>>> >>>>>> This is understandable as the Function object which wraps the >>>>>> module doesn't know about "foomodule.js". >>>>>> >>>>>> So.. my question is.. how do I tell the Function object that the >>>>>> "filename" it should use when exceptions are thrown from it is >>>>>> "foomodule.js"? >>>>>> >>>>>> I have tried the following and none work: >>>>>> >>>>>> var func = new Function(args, body); >>>>>> func.name = "foomodule.js"; >>>>>> func.fileName = "foomodule.js"; >>>>>> func.displayName = "foomodule.js"; >>>>>> >>>>>> Any insights would be greatly appreciated. >>>>>> >>>>>> >>>>>> >>>>>> >>>>> >>>> >>> >> > From timvolpe at gmail.com Wed Feb 18 14:00:47 2015 From: timvolpe at gmail.com (Tim Fox) Date: Wed, 18 Feb 2015 14:00:47 +0000 Subject: How to set correct fileName for exceptions thrown from a function in a Function object In-Reply-To: <54E494A5.8060901@oracle.com> References: <54E45DFD.4030607@gmail.com> <54E462C7.5040402@gmail.com> <54E46563.8040707@oracle.com> <54E48912.1030308@gmail.com> <54E48FDD.8070504@oracle.com> <54E49367.7000103@gmail.com> <54E494A5.8060901@oracle.com> Message-ID: <54E49B0F.6090004@gmail.com> On 18/02/15 13:33, A. Sundararajan wrote: > So, did you fix "// #sourceURL" to //# sourceURL" ? Note on the > whitespace: no whitespace between '//' and '#' and single whitespace > after '#' ? Bingo, that worked :) So I now have exceptions thrown from evals showing correct lineNumber, fileName and stack for all exceptions apart from SyntaxError. I've created another example here: https://gist.github.com/purplefox/f99ad4c78d246d2d6aee In this example, the eval has a Syntax Error (e.g. the user is trying require a module with a syntax error in it). What I see is that the caught exception corresponds to where the eval() was _executed_, not to the place in the eval code where the syntax error actually is. Interestingly the correct information *is* available if I do a bit of digging - two references deep from the caught exception there's the exception that we're actually interested in with the correct lineNumber, (but not correct fileName). I'd expect the caught exception to correspond to the actual SyntaxError in the code not to where the eval was invoked - this would be consistent with how the other error types are handled, and it would be a lot more useful for the user, as what they want to know is where in their code the problem actually is. > > Release notes page here says the fix is in 8u20. > http://www.oracle.com/technetwork/java/javase/2col/8u20-bugfixes-2257730.html. > Bug id is http://bugs.java.com/view_bug.do?bug_id=8032068 > > -Sundar > > On Wednesday 18 February 2015 06:58 PM, Tim Fox wrote: >> On 18/02/15 13:13, A. Sundararajan wrote: >>> >>> Hi Tim, >>> >>> It was added in 8u20 if I recall right. >>> >>> jjs -version >>> nashorn 1.8.0_40 >>> jjs> >>> jjs> eval("f() //# sourceURL=t.js") >>> t.js:1 ReferenceError: "f" is not defined >>> jjs> eval("g() //@ sourceURL=g.js") >>> g.js:1 ReferenceError: "g" is not defined >>> >>> I think your file has "// #sourceURL=wibble.js". Please try changing >>> it as "//# sourceFile=wibble.js" >> >> Ok, I am confused now... I have tried both #sourceURL (which most of >> the google hits say to use) and #sourceFile and neither seem to work ;) >> >> I've also tried @sourceURL which some other links say to use. (Yay >> for consistency ;) ) >> >> Nothing seems to work so far. >> >> I am using nashorn 1.8.0_25 which is the latest version in the >> production Oracle JDK afaict. Do I have to use OpenJDK to get these >> changes? I don't think this will be an option as most of users use >> the Oracle JDK. >> >>> >>> See also: >>> https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Debug_eval_sources >>> >>> -Sundar >>> >>> On Wednesday 18 February 2015 06:14 PM, Tim Fox wrote: >>>> Hi Sundar, >>>> >>>> I tried the sourceURL trick: >>>> >>>> https://gist.github.com/purplefox/60619067006c3cc3eaee >>>> >>>> But it doesn't seem to work. I suspect because the parsing of the >>>> eval fails before it gets to the last line (?) :( >>>> >>>> I'm going to give a go with load()... >>>> >>>> On 18/02/15 10:11, A. Sundararajan wrote: >>>>> you can use >>>>> >>>>> 1) "load" from object - object with name and script properties. >>>>> >>>>> 2) or use 'eval' naming // #sourceURL comment >>>>> >>>>> as mentioned here: >>>>> >>>>> http://mail.openjdk.java.net/pipermail/nashorn-dev/2014-July/003174.html >>>>> >>>>> >>>>> Can code for body of module function be something like >>>>> "eval(readScriptAsText() + "\n// #sourceURL=" + name)" ? >>>>> >>>>> Hope this helps, >>>>> -Sundar >>>>> >>>>> On Wednesday 18 February 2015 03:30 PM, Tim Fox wrote: >>>>>> I've added a simple reproducer that you can run in the repl: >>>>>> >>>>>> https://gist.github.com/purplefox/b03a2a6263c26e3206da >>>>>> >>>>>> Another observation is that line number is reported as 6, when it >>>>>> should be 5 (assuming the first line is line 1 which is normal >>>>>> convention afaik) >>>>>> >>>>>> On 18/02/15 09:40, Tim Fox wrote: >>>>>>> Hi all, >>>>>>> >>>>>>> I'm currently using a CommonJS/npm modules require >>>>>>> implementation (npm-jvm) with Nashorn. >>>>>>> >>>>>>> Roughly, the way it works (and I'm sure you're already familiar >>>>>>> with this technique) is it takes the JavaScript module and wraps >>>>>>> it in a Function object: >>>>>>> >>>>>>> var body = readScriptAsText(); >>>>>>> var args = ['exports', 'module', 'require', '__filename', >>>>>>> '__dirname']; >>>>>>> var func = new Function(args, body); >>>>>>> func.apply(module, [module.exports, module, module.require, >>>>>>> module.filename, dir]); // Execute it - this works fine >>>>>>> >>>>>>> Now let's say the actual module (foomodule.js) we are loading >>>>>>> contains this: >>>>>>> >>>>>>> module.exports = function() { >>>>>>> var num = 234; >>>>>>> num.substr(1, 1); // Will throw TypeError here >>>>>>> } >>>>>>> >>>>>>> I.e. it simply exports a function, which will throw a TypeError >>>>>>> when it's executed. >>>>>>> >>>>>>> When the exported function is executed it does indeed throw a >>>>>>> TypeError: >>>>>>> >>>>>>> var f = require("foomodule"); >>>>>>> >>>>>>> f(); // Throws TypeError >>>>>>> >>>>>>> Unfortunately the fileName field of the TypeError is set to >>>>>>> "" not to "foomodule.js", which is unfriendly for the >>>>>>> user. >>>>>>> >>>>>>> This is understandable as the Function object which wraps the >>>>>>> module doesn't know about "foomodule.js". >>>>>>> >>>>>>> So.. my question is.. how do I tell the Function object that the >>>>>>> "filename" it should use when exceptions are thrown from it is >>>>>>> "foomodule.js"? >>>>>>> >>>>>>> I have tried the following and none work: >>>>>>> >>>>>>> var func = new Function(args, body); >>>>>>> func.name = "foomodule.js"; >>>>>>> func.fileName = "foomodule.js"; >>>>>>> func.displayName = "foomodule.js"; >>>>>>> >>>>>>> Any insights would be greatly appreciated. >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> > From timvolpe at gmail.com Wed Feb 18 14:59:59 2015 From: timvolpe at gmail.com (Tim Fox) Date: Wed, 18 Feb 2015 14:59:59 +0000 Subject: Problems with SyntaxError construction Message-ID: <54E4A8EF.6090906@gmail.com> Hi all, I've started a new thread for this, so as not to clutter the previous thread on exceptions. I've come across a possible issue with creating SyntaxError objects (and potentially other exceptions although I haven't tested them). https://gist.github.com/purplefox/dfe30a38098c1708e24b In the above gist I create a SyntaxError specifying message, fileName, and lineNumber. However fileName and lineNumber appear to be ignored, and instead the SyntaxError fileName and lineNumber are set to the fileName of the file where it was created and the lineNumber of the creation. I'm not sure if I'm doing something wrong, but according to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError I should be able to create SyntaxError objects like this. There appears to be a further issue. If I then throw the syntax error from the JS script, and catch it in Java like this: try { engine.eval(script); } catch (ScriptException e) { System.out.println("message:" + e.getMessage()); System.out.println("fileName:" + e.getFileName()); System.out.println("lineNumber:" + e.getLineNumber()); } Then the message, fileName and lineNumber always correspond to place where the object was created, not to the subsequently set values. In other words, I can't figure out a way of creating a SyntaxError object in JS with my own values of fileName and lineNumber and have those values available in Java when caught. Any ideas from the experts? :) From bliang at linkedin.com Thu Feb 19 03:01:38 2015 From: bliang at linkedin.com (Bernard Liang) Date: Thu, 19 Feb 2015 03:01:38 +0000 Subject: Nashorn performance regression from JDK8u5 to JDK8u25? In-Reply-To: References: <546A64C8.9040503@oracle.com> <54745A4C.3060106@oracle.com> <547C7E29.9070001@oracle.com> Message-ID: Hannes/Marcus, We haven?t heard any updates on this in the past 2 months or so. Was there some progress made during that time? Regards, Bernard Liang On 12/7/14, 10:22 PM, "Bernard Liang" wrote: >Hannes, > >I tried out your methodology with the basic template + json that I >provided earlier, as well as with the substantially larger templates + >json I mentioned. In this pure form of the test, I did see that in the >long term, u40 (with -Dnashorn.fields.objects=true; without this it was >indeed much worse like you found) and u25 does seem to outperform u5 by a >noticeable margin (with u40 slightly edging out u25), and with all >versions requiring 10,000-15,000 iterations to reach their peak >performance. However, in the first roughly 8,000-10,000 iterations, they >were up to 2x slower than u5 in terms of time taken, with the average >closer to 1.5x. Is this expected, and could it be remedied somehow? As it >stands, the later versions do seem to have superior long-term performance, >but we would have to accept the penalty of relatively poorer performance >during quite a long initial phase. You can reproduce the same results with >the basic templates. > >Regards, >Bernard Liang > >On 12/1/14, 6:41 AM, "Hannes Wallnoefer" >wrote: > >>Hi Bernard, >> >>Sorry for sending this message a second time, first one was rejected by >>nashorn-dev because of the attachment. >> >>I looked at performance of dust.js with various versions of Nashorn. I >>didn't see a regression between 8u05 and 8u25, quite the contrary, it >>seems that u25 is about 30% faster after warmup. However, it does look >>like startup and warmup is a bit more inconsistent with u25. It >>sometimes takes a bit longer to reach final speed. >> >>With 8u40 I noticed a pretty dramatic performance regression right away, >>it's about 3-4x slower than 8u05 and 8u25. The culprit turns out to be >>our dual fields representation which is turned on by default in u40. >>When that feature is disabled, u40 is even a bit faster than u25, and >>also warmup seems to be smoother again. >> >>You can test running with dual fields disabled by setting the >>"nashorn.fields.objects" system property to "true", for example by >>adding -Dnashorn.fields.objects=true to the command line. >> >>I'm pasting in the script I used for benchmarking below. You can run it >>along with the templates you sent with the following command line: >> >> > jjs -Dnashorn.fields.objects=true -scripting dust-bench.js >> >>Let me know if my benchmark does not measure what is relevant to your >>application. It's possible for example that you're repeatedly calling >>into nashorn script engines and there's some potential issues with that >>(you should reuse the same script engine if possible). >> >>Regards, >>Hannes >> >>===== begin dust-bench.js ===== >> >>if (!this.readFully) readFully = read; >> >>load("dist/dust-full.js"); >>var template = readFully("basic.tl"); >>var compiled = dust.compile(template, "basic"); >>print("compiled"); >>dust.loadSource(compiled); >>print("loaded"); >>var json = JSON.parse(readFully("basic.json")); >>print("read json"); >>print(); >> >> >>function bench(n) { >> var start = Date.now(); >> for (var i = 0; i < 2000; i++) { >> dust.render("basic", json, function(err, out) { >> if (err) throw err; >> }); >> } >> >> print(n, "done", Date.now() - start); >>} >> >>for (var i = 0; i < 200; i++) { >> bench(i); >>} >> >>===== end dust-bench.js ===== >> >>Am 2014-11-25 um 20:28 schrieb Bernard Liang: >>> Hannes, >>> >>> Sure, I?ve reproduced the data you requested below, as they are small >>> enough to fit comfortably in a standard message. However, in addition I >>> would still like to reiterate the questions from my previous reply, >>> regarding across-build Nashorn-related changes and performance >>>benchmarks. >>> >>> Your reply also suggests that you have some familiarity with Dust, but >>>if >>> that is not the case, I can certainly provide some more details. >>> >>> Regards, >>> Bernard Liang >>> >>> ===== begin basic.tl ===== >>> {~n} >>> {~n} >>> {page_title}{~n} >>> {~n} >>> {~n} >>>
    {~n} >>> {#names} >>>
  • {title} {name}
  • {~n} >>> {/names} >>>
{~n} >>> {~n} >>> >>> >>> ===== end basic.tl ===== >>> ===== begin basic.json ===== >>> { >>> "page_title": "Benchmark", >>> "title": "Sir", >>> "names": [{ >>> "name": "Moe" >>> }, >>> { >>> "name": "Larry" >>> }, >>> { >>> "name": "Curly" >>> }] >>> } >>> ===== end basic.json ===== >>> >>> >>> On 11/25/14, 2:30 AM, "Hannes Wallnoefer" >>> >>> wrote: >>> >>>> Hi Bernard, >>>> >>>> I'm trying to reproduce your problems. In your first mail to the list >>>> you wrote you attached a Dust template and JSON data. I think you >>>>either >>>> forgot to attach it, or it was stripped by the list software. Can you >>>> please try to send it again, or put it somewhere we can download it? >>>> >>>> Thanks, >>>> Hannes >>>> >>>> Am 2014-11-18 um 03:21 schrieb Bernard Liang: >>>>> Michel et al, >>>>> >>>>> I?ve run our local test battery using the link you provided, and >>>>>while >>>>> in some cases there is improvement, overall the performance still >>>>>seems >>>>> to be closer to u25 levels than u5 levels. For what it?s worth, I did >>>>> notice that the performance improvements from u25 to u40 were >>>>>generally >>>>> better in pooled environments than ones where a single instance of >>>>>the >>>>> execution environment was running per thread. This leads itself to a >>>>>few >>>>> questions, some of which are reiterated from the original inquiry: >>>>> >>>>> * Is anyone familiar with (significant) specific changes in the >>>>> Nashorn libraries from u5 => u25 => u40 that might be related to this >>>>> regression and could explain the u25 and/or u40 changes in more >>>>>detail >>>>> (that might have led to the recommendation to use u40)? >>>>> * Do you have any performance suites (internal or other) that >>>>>test >>>>> various Nashorn benchmarks across different releases (of JDK8, for >>>>> instance)? Do the results of those correlate with our findings? >>>>> >>>>> Regards, >>>>> Bernard Liang >>>>> >>>>> PS. The output of `java -version` most recently tested was as >>>>>follows: >>>>> >>>>> java version "1.8.0_40-ea" >>>>> >>>>> Java(TM) SE Runtime Environment (build 1.8.0_40-ea-b12) >>>>> >>>>> Java HotSpot(TM) 64-Bit Server VM (build 25.40-b16, mixed mode) >>>>> >>>>> Previous versions tested: >>>>> >>>>> java version "1.8.0_25" >>>>> >>>>> Java(TM) SE Runtime Environment (build 1.8.0_25-b17) >>>>> >>>>> Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode) >>>>> >>>>> java version "1.8.0_05" >>>>> >>>>> Java(TM) SE Runtime Environment (build 1.8.0_05-b13) >>>>> >>>>> Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode) >>>>> >>>>> From: Michel Trudeau >>>>> > >>>>> Date: Monday, November 17, 2014 at 1:12 PM >>>>> To: Bernard Liang > >>>>> Cc: >>>>>"nashorn-dev at openjdk.java.net" >>>>> > >>>>> Subject: Re: Nashorn performance regression from JDK8u5 to JDK8u25? >>>>> >>>>> Bernard, >>>>> >>>>> It'd be great if you could try the latest 8u40 stable build. We are >>>>> planning to release 8u40 early in the new year. >>>>> >>>>> https://jdk8.java.net/download.html >>>>> >>>>> We also have an optional optimizer in 8u40, enable it with the >>>>>command >>>>> line argument '-ot'. >>>>> >>>>> Thanks, >>>>> Michel >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> Bernard Liang wrote: >>>>> >>>>> Hello, >>>>> >>>>> After running some performance tests on the Cartesian product of >>>>> ([JDK8u5, JDK8u25] x [simple template, complex templates] x >>>>> [all-or-nothing, streaming chunks] x [single dust instance per >>>>>thread, >>>>> pooled dust instances] x [blank Dust instances, Dust instances with >>>>> templates preloaded]), we find that JDK8u25 performance is very >>>>> consistently considerably worse than JDK8u5 (by roughly 10-100%, with >>>>> the average falling somewhere between there). The relevant code has >>>>>been >>>>> executed enough times (on the order of 10,000 times) to reach >>>>>reasonably >>>>> warmed-up states. If some of the items on the axes of the Cartesian >>>>> product don?t make much sense, you can ignore the fuzzy parts of the >>>>> detailed breakdown for now, with the general understanding that >>>>>various >>>>> different environments have been tested and shown to yield the same >>>>> results. >>>>> >>>>> Some additional high-level context: >>>>> >>>>> Dust is basically a templating language used to render JSON data into >>>>> HTML with compilable ?templates": https://github.com/linkedin/dustjs >>>>>(we >>>>> are at the v2.4.2 tag) >>>>> >>>>> ?simple template? = ~150 bytes each of one (precompiled) template + >>>>> context JSON (attached) >>>>> ?complex templates? = ~350 compiled templates spanning ~245KB in >>>>> compiled JS + ~75KB of JSON context (proprietary data) >>>>> >>>>> >From >>>>> https://blogs.oracle.com/nashorn/entry/latest_news_from_the_nashorn, >>>>>it >>>>> sounded like there were some recent updates made to Nashorn >>>>>performance >>>>> around the u20 mark, but that seems to have caused a regression >>>>>rather >>>>> than an improvement. Is this something that nashorn-dev is aware of? >>>>>Is >>>>> there any way we can help diagnose the issue further using publicly >>>>>safe >>>>> data? (If you?re looking for a way to reproduce this, the attached >>>>>basic >>>>> Dust template + JSON context should be adequate under almost any >>>>> environment.) >>>>> >>>>> Regards, >>>>> Bernard Liang >>>>> >> > From attila.szegedi at oracle.com Thu Feb 19 17:48:35 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Thu, 19 Feb 2015 18:48:35 +0100 Subject: Review request for JDK-8072426 Message-ID: Please review JDK-8072426 at for This is what basically became an epic yak shaving exercise after we determined that POJOs aren't subjected to ToPrimitive (earlier known as java.math.RoundingMode.UP != "UP" problem). While we originally advocated for throwing TypeError for POJOs [[DefaultValue]] that would've prevented their implicit toString() in string concatenation too. Instead, I opted to fix this once and forever but it turned out that the biggest issue with it is the fact that JSObject was also not handled correctly for ToPrimitive; fixing that turned out to be the most challenging part, introducing a new JSObject.getDefaultValue() method and deprecating JSObject.toNumber() (which isn't used anymore at all). As an unexpected boon, JSObjectLinker no longer needs to do any conversions, so its GuardingTypeConverterFactory functionality has been entirely removed. NashornPrimitiveLinker will now automatically take care of converting JSObject instances to various primitive types, as per specification behavior. Finally, the ScriptRuntime changes to the equals() and equalDifferentType() are purely refactoring of some common type testing subexpressions and conversions, as well as short-circuiting of some comparisons. They aren't strictly necessary for this issue, but just for clear understanding of what's happening it seemed like a good idea to make them more concise (ScriptRuntime.EQ and .NE, of which the two affected methods are sub-parts are also not invoked terribly often, and I'll soon make them be invoked even less frequently.) Thanks, Attila. From hannes.wallnoefer at oracle.com Thu Feb 19 18:35:54 2015 From: hannes.wallnoefer at oracle.com (Hannes Wallnoefer) Date: Thu, 19 Feb 2015 19:35:54 +0100 Subject: Nashorn performance regression from JDK8u5 to JDK8u25? In-Reply-To: References: <546A64C8.9040503@oracle.com> <54745A4C.3060106@oracle.com> <547C7E29.9070001@oracle.com> Message-ID: <54E62D0A.2060505@oracle.com> Bernard, The primary issue with dust.js has been fixed in JDK9 and backported to JDK8u40, which will be out soon. https://bugs.openjdk.java.net/browse/JDK-8066669 You can download the 8u40 early access release here: https://jdk8.java.net/download.html In my tests 8u40 preview release is now as fast or a little bit faster than 8u25. Hannes Am 2015-02-19 um 04:01 schrieb Bernard Liang: > Hannes/Marcus, > > We haven?t heard any updates on this in the past 2 months or so. Was there > some progress made during that time? > > Regards, > Bernard Liang > > On 12/7/14, 10:22 PM, "Bernard Liang" wrote: > >> Hannes, >> >> I tried out your methodology with the basic template + json that I >> provided earlier, as well as with the substantially larger templates + >> json I mentioned. In this pure form of the test, I did see that in the >> long term, u40 (with -Dnashorn.fields.objects=true; without this it was >> indeed much worse like you found) and u25 does seem to outperform u5 by a >> noticeable margin (with u40 slightly edging out u25), and with all >> versions requiring 10,000-15,000 iterations to reach their peak >> performance. However, in the first roughly 8,000-10,000 iterations, they >> were up to 2x slower than u5 in terms of time taken, with the average >> closer to 1.5x. Is this expected, and could it be remedied somehow? As it >> stands, the later versions do seem to have superior long-term performance, >> but we would have to accept the penalty of relatively poorer performance >> during quite a long initial phase. You can reproduce the same results with >> the basic templates. >> >> Regards, >> Bernard Liang >> >> On 12/1/14, 6:41 AM, "Hannes Wallnoefer" >> wrote: >> >>> Hi Bernard, >>> >>> Sorry for sending this message a second time, first one was rejected by >>> nashorn-dev because of the attachment. >>> >>> I looked at performance of dust.js with various versions of Nashorn. I >>> didn't see a regression between 8u05 and 8u25, quite the contrary, it >>> seems that u25 is about 30% faster after warmup. However, it does look >>> like startup and warmup is a bit more inconsistent with u25. It >>> sometimes takes a bit longer to reach final speed. >>> >>> With 8u40 I noticed a pretty dramatic performance regression right away, >>> it's about 3-4x slower than 8u05 and 8u25. The culprit turns out to be >>> our dual fields representation which is turned on by default in u40. >>> When that feature is disabled, u40 is even a bit faster than u25, and >>> also warmup seems to be smoother again. >>> >>> You can test running with dual fields disabled by setting the >>> "nashorn.fields.objects" system property to "true", for example by >>> adding -Dnashorn.fields.objects=true to the command line. >>> >>> I'm pasting in the script I used for benchmarking below. You can run it >>> along with the templates you sent with the following command line: >>> >>>> jjs -Dnashorn.fields.objects=true -scripting dust-bench.js >>> Let me know if my benchmark does not measure what is relevant to your >>> application. It's possible for example that you're repeatedly calling >>> into nashorn script engines and there's some potential issues with that >>> (you should reuse the same script engine if possible). >>> >>> Regards, >>> Hannes >>> >>> ===== begin dust-bench.js ===== >>> >>> if (!this.readFully) readFully = read; >>> >>> load("dist/dust-full.js"); >>> var template = readFully("basic.tl"); >>> var compiled = dust.compile(template, "basic"); >>> print("compiled"); >>> dust.loadSource(compiled); >>> print("loaded"); >>> var json = JSON.parse(readFully("basic.json")); >>> print("read json"); >>> print(); >>> >>> >>> function bench(n) { >>> var start = Date.now(); >>> for (var i = 0; i < 2000; i++) { >>> dust.render("basic", json, function(err, out) { >>> if (err) throw err; >>> }); >>> } >>> >>> print(n, "done", Date.now() - start); >>> } >>> >>> for (var i = 0; i < 200; i++) { >>> bench(i); >>> } >>> >>> ===== end dust-bench.js ===== >>> >>> Am 2014-11-25 um 20:28 schrieb Bernard Liang: >>>> Hannes, >>>> >>>> Sure, I?ve reproduced the data you requested below, as they are small >>>> enough to fit comfortably in a standard message. However, in addition I >>>> would still like to reiterate the questions from my previous reply, >>>> regarding across-build Nashorn-related changes and performance >>>> benchmarks. >>>> >>>> Your reply also suggests that you have some familiarity with Dust, but >>>> if >>>> that is not the case, I can certainly provide some more details. >>>> >>>> Regards, >>>> Bernard Liang >>>> >>>> ===== begin basic.tl ===== >>>> {~n} >>>> {~n} >>>> {page_title}{~n} >>>> {~n} >>>> {~n} >>>>
    {~n} >>>> {#names} >>>>
  • {title} {name}
  • {~n} >>>> {/names} >>>>
{~n} >>>> {~n} >>>> >>>> >>>> ===== end basic.tl ===== >>>> ===== begin basic.json ===== >>>> { >>>> "page_title": "Benchmark", >>>> "title": "Sir", >>>> "names": [{ >>>> "name": "Moe" >>>> }, >>>> { >>>> "name": "Larry" >>>> }, >>>> { >>>> "name": "Curly" >>>> }] >>>> } >>>> ===== end basic.json ===== >>>> >>>> >>>> On 11/25/14, 2:30 AM, "Hannes Wallnoefer" >>>> >>>> wrote: >>>> >>>>> Hi Bernard, >>>>> >>>>> I'm trying to reproduce your problems. In your first mail to the list >>>>> you wrote you attached a Dust template and JSON data. I think you >>>>> either >>>>> forgot to attach it, or it was stripped by the list software. Can you >>>>> please try to send it again, or put it somewhere we can download it? >>>>> >>>>> Thanks, >>>>> Hannes >>>>> >>>>> Am 2014-11-18 um 03:21 schrieb Bernard Liang: >>>>>> Michel et al, >>>>>> >>>>>> I?ve run our local test battery using the link you provided, and >>>>>> while >>>>>> in some cases there is improvement, overall the performance still >>>>>> seems >>>>>> to be closer to u25 levels than u5 levels. For what it?s worth, I did >>>>>> notice that the performance improvements from u25 to u40 were >>>>>> generally >>>>>> better in pooled environments than ones where a single instance of >>>>>> the >>>>>> execution environment was running per thread. This leads itself to a >>>>>> few >>>>>> questions, some of which are reiterated from the original inquiry: >>>>>> >>>>>> * Is anyone familiar with (significant) specific changes in the >>>>>> Nashorn libraries from u5 => u25 => u40 that might be related to this >>>>>> regression and could explain the u25 and/or u40 changes in more >>>>>> detail >>>>>> (that might have led to the recommendation to use u40)? >>>>>> * Do you have any performance suites (internal or other) that >>>>>> test >>>>>> various Nashorn benchmarks across different releases (of JDK8, for >>>>>> instance)? Do the results of those correlate with our findings? >>>>>> >>>>>> Regards, >>>>>> Bernard Liang >>>>>> >>>>>> PS. The output of `java -version` most recently tested was as >>>>>> follows: >>>>>> >>>>>> java version "1.8.0_40-ea" >>>>>> >>>>>> Java(TM) SE Runtime Environment (build 1.8.0_40-ea-b12) >>>>>> >>>>>> Java HotSpot(TM) 64-Bit Server VM (build 25.40-b16, mixed mode) >>>>>> >>>>>> Previous versions tested: >>>>>> >>>>>> java version "1.8.0_25" >>>>>> >>>>>> Java(TM) SE Runtime Environment (build 1.8.0_25-b17) >>>>>> >>>>>> Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode) >>>>>> >>>>>> java version "1.8.0_05" >>>>>> >>>>>> Java(TM) SE Runtime Environment (build 1.8.0_05-b13) >>>>>> >>>>>> Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode) >>>>>> >>>>>> From: Michel Trudeau >>>>>> > >>>>>> Date: Monday, November 17, 2014 at 1:12 PM >>>>>> To: Bernard Liang > >>>>>> Cc: >>>>>> "nashorn-dev at openjdk.java.net" >>>>>> > >>>>>> Subject: Re: Nashorn performance regression from JDK8u5 to JDK8u25? >>>>>> >>>>>> Bernard, >>>>>> >>>>>> It'd be great if you could try the latest 8u40 stable build. We are >>>>>> planning to release 8u40 early in the new year. >>>>>> >>>>>> https://jdk8.java.net/download.html >>>>>> >>>>>> We also have an optional optimizer in 8u40, enable it with the >>>>>> command >>>>>> line argument '-ot'. >>>>>> >>>>>> Thanks, >>>>>> Michel >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> Bernard Liang wrote: >>>>>> >>>>>> Hello, >>>>>> >>>>>> After running some performance tests on the Cartesian product of >>>>>> ([JDK8u5, JDK8u25] x [simple template, complex templates] x >>>>>> [all-or-nothing, streaming chunks] x [single dust instance per >>>>>> thread, >>>>>> pooled dust instances] x [blank Dust instances, Dust instances with >>>>>> templates preloaded]), we find that JDK8u25 performance is very >>>>>> consistently considerably worse than JDK8u5 (by roughly 10-100%, with >>>>>> the average falling somewhere between there). The relevant code has >>>>>> been >>>>>> executed enough times (on the order of 10,000 times) to reach >>>>>> reasonably >>>>>> warmed-up states. If some of the items on the axes of the Cartesian >>>>>> product don?t make much sense, you can ignore the fuzzy parts of the >>>>>> detailed breakdown for now, with the general understanding that >>>>>> various >>>>>> different environments have been tested and shown to yield the same >>>>>> results. >>>>>> >>>>>> Some additional high-level context: >>>>>> >>>>>> Dust is basically a templating language used to render JSON data into >>>>>> HTML with compilable ?templates": https://github.com/linkedin/dustjs >>>>>> (we >>>>>> are at the v2.4.2 tag) >>>>>> >>>>>> ?simple template? = ~150 bytes each of one (precompiled) template + >>>>>> context JSON (attached) >>>>>> ?complex templates? = ~350 compiled templates spanning ~245KB in >>>>>> compiled JS + ~75KB of JSON context (proprietary data) >>>>>> >>>>>>> From >>>>>> https://blogs.oracle.com/nashorn/entry/latest_news_from_the_nashorn, >>>>>> it >>>>>> sounded like there were some recent updates made to Nashorn >>>>>> performance >>>>>> around the u20 mark, but that seems to have caused a regression >>>>>> rather >>>>>> than an improvement. Is this something that nashorn-dev is aware of? >>>>>> Is >>>>>> there any way we can help diagnose the issue further using publicly >>>>>> safe >>>>>> data? (If you?re looking for a way to reproduce this, the attached >>>>>> basic >>>>>> Dust template + JSON context should be adequate under almost any >>>>>> environment.) >>>>>> >>>>>> Regards, >>>>>> Bernard Liang >>>>>> From marcus.lagergren at oracle.com Thu Feb 19 18:50:13 2015 From: marcus.lagergren at oracle.com (Marcus Lagergren) Date: Thu, 19 Feb 2015 19:50:13 +0100 Subject: Review request for JDK-8072426 In-Reply-To: References: Message-ID: OK. I think I?ve figured out how this works now and gone through the code. +1 /M > On 19 Feb 2015, at 18:48, Attila Szegedi wrote: > > Please review JDK-8072426 at for > > This is what basically became an epic yak shaving exercise after we determined that POJOs aren't subjected to ToPrimitive (earlier known as java.math.RoundingMode.UP != "UP" problem). While we originally advocated for throwing TypeError for POJOs [[DefaultValue]] that would've prevented their implicit toString() in string concatenation too. Instead, I opted to fix this once and forever but it turned out that the biggest issue with it is the fact that JSObject was also not handled correctly for ToPrimitive; fixing that turned out to be the most challenging part, introducing a new JSObject.getDefaultValue() method and deprecating JSObject.toNumber() (which isn't used anymore at all). > > As an unexpected boon, JSObjectLinker no longer needs to do any conversions, so its GuardingTypeConverterFactory functionality has been entirely removed. NashornPrimitiveLinker will now automatically take care of converting JSObject instances to various primitive types, as per specification behavior. > > Finally, the ScriptRuntime changes to the equals() and equalDifferentType() are purely refactoring of some common type testing subexpressions and conversions, as well as short-circuiting of some comparisons. They aren't strictly necessary for this issue, but just for clear understanding of what's happening it seemed like a good idea to make them more concise (ScriptRuntime.EQ and .NE, of which the two affected methods are sub-parts are also not invoked terribly often, and I'll soon make them be invoked even less frequently.) > > Thanks, > Attila. From sundararajan.athijegannathan at oracle.com Fri Feb 20 08:01:58 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Fri, 20 Feb 2015 13:31:58 +0530 Subject: Review request for JDK-8072426 In-Reply-To: References: Message-ID: <54E6E9F6.4020305@oracle.com> * http://cr.openjdk.java.net/~attila/8072426/webrev.00/test/script/basic/JDK-8072426.js.html has copyright year to be 2014 +1 apart from that. -Sundar On Thursday 19 February 2015 11:18 PM, Attila Szegedi wrote: > Please review JDK-8072426 at for > > This is what basically became an epic yak shaving exercise after we determined that POJOs aren't subjected to ToPrimitive (earlier known as java.math.RoundingMode.UP != "UP" problem). While we originally advocated for throwing TypeError for POJOs [[DefaultValue]] that would've prevented their implicit toString() in string concatenation too. Instead, I opted to fix this once and forever but it turned out that the biggest issue with it is the fact that JSObject was also not handled correctly for ToPrimitive; fixing that turned out to be the most challenging part, introducing a new JSObject.getDefaultValue() method and deprecating JSObject.toNumber() (which isn't used anymore at all). > > As an unexpected boon, JSObjectLinker no longer needs to do any conversions, so its GuardingTypeConverterFactory functionality has been entirely removed. NashornPrimitiveLinker will now automatically take care of converting JSObject instances to various primitive types, as per specification behavior. > > Finally, the ScriptRuntime changes to the equals() and equalDifferentType() are purely refactoring of some common type testing subexpressions and conversions, as well as short-circuiting of some comparisons. They aren't strictly necessary for this issue, but just for clear understanding of what's happening it seemed like a good idea to make them more concise (ScriptRuntime.EQ and .NE, of which the two affected methods are sub-parts are also not invoked terribly often, and I'll soon make them be invoked even less frequently.) > > Thanks, > Attila. From sundararajan.athijegannathan at oracle.com Fri Feb 20 08:09:40 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Fri, 20 Feb 2015 13:39:40 +0530 Subject: Problems with SyntaxError construction In-Reply-To: <54E4A8EF.6090906@gmail.com> References: <54E4A8EF.6090906@gmail.com> Message-ID: <54E6EBC4.7020108@oracle.com> * SyntaxError constructor accepting extra arguments apart from message is not as per ECMAScript standard. That one is Firefox/Mozilla specific extension. We try to *add* properties, functions for extension - try not to modify/extend standard defined functions, constructors. * User can fileName, lineNumber and columnNumber of constructed SyntaxError instance. * On the java side, the NashornException and ScriptException's file, line, column use the actual throw point from the script source. While this can read the values from SyntaxError or any Error for that matter, there is a problem. fileName, lineNumber, columnNumber could be set to any value in script. These have to be converted to String, int, int respectively. Conversion means calling [[DefaultValue]] with String, Number hint - which is calling out to script code. This process can itself throw exception!! All this may destroy info. on where exactly the underlying exception was thrown. * There is clear workaround. Script code can always read SyntaxError instance's fileName, lineNumber etc. - which can be set to anything post construction. Java code can get underling ECMA error instance via NashornException.getEcmaError - which would return a ScriptObjectMirror. Java code can call ScriptObjectMirror.getMember("fileName") etc. to retrieve properties set by user's script. Hope this helps, -Sundar On Wednesday 18 February 2015 08:29 PM, Tim Fox wrote: > Hi all, > > I've started a new thread for this, so as not to clutter the previous > thread on exceptions. > > I've come across a possible issue with creating SyntaxError objects > (and potentially other exceptions although I haven't tested them). > > https://gist.github.com/purplefox/dfe30a38098c1708e24b > > In the above gist I create a SyntaxError specifying message, fileName, > and lineNumber. > > However fileName and lineNumber appear to be ignored, and instead the > SyntaxError fileName and lineNumber are set to the fileName of the > file where it was created and the lineNumber of the creation. > > I'm not sure if I'm doing something wrong, but according to > https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError > I should be able to create SyntaxError objects like this. > > There appears to be a further issue. If I then throw the syntax error > from the JS script, and catch it in Java like this: > > try { > engine.eval(script); > } catch (ScriptException e) { > System.out.println("message:" + e.getMessage()); > System.out.println("fileName:" + e.getFileName()); > System.out.println("lineNumber:" + e.getLineNumber()); > } > > Then the message, fileName and lineNumber always correspond to place > where the object was created, not to the subsequently set values. > > In other words, I can't figure out a way of creating a SyntaxError > object in JS with my own values of fileName and lineNumber and have > those values available in Java when caught. > > Any ideas from the experts? :) > > From hannes.wallnoefer at oracle.com Fri Feb 20 08:48:05 2015 From: hannes.wallnoefer at oracle.com (Hannes Wallnoefer) Date: Fri, 20 Feb 2015 09:48:05 +0100 Subject: Review request for JDK-8072426 In-Reply-To: References: Message-ID: <54E6F4C5.1090402@oracle.com> +1 Nice work! Am 2015-02-19 um 18:48 schrieb Attila Szegedi: > Please review JDK-8072426 at for > > This is what basically became an epic yak shaving exercise after we determined that POJOs aren't subjected to ToPrimitive (earlier known as java.math.RoundingMode.UP != "UP" problem). While we originally advocated for throwing TypeError for POJOs [[DefaultValue]] that would've prevented their implicit toString() in string concatenation too. Instead, I opted to fix this once and forever but it turned out that the biggest issue with it is the fact that JSObject was also not handled correctly for ToPrimitive; fixing that turned out to be the most challenging part, introducing a new JSObject.getDefaultValue() method and deprecating JSObject.toNumber() (which isn't used anymore at all). > > As an unexpected boon, JSObjectLinker no longer needs to do any conversions, so its GuardingTypeConverterFactory functionality has been entirely removed. NashornPrimitiveLinker will now automatically take care of converting JSObject instances to various primitive types, as per specification behavior. > > Finally, the ScriptRuntime changes to the equals() and equalDifferentType() are purely refactoring of some common type testing subexpressions and conversions, as well as short-circuiting of some comparisons. They aren't strictly necessary for this issue, but just for clear understanding of what's happening it seemed like a good idea to make them more concise (ScriptRuntime.EQ and .NE, of which the two affected methods are sub-parts are also not invoked terribly often, and I'll soon make them be invoked even less frequently.) > > Thanks, > Attila. From timvolpe at gmail.com Fri Feb 20 09:41:07 2015 From: timvolpe at gmail.com (Tim Fox) Date: Fri, 20 Feb 2015 09:41:07 +0000 Subject: Problems with SyntaxError construction In-Reply-To: <54E6EBC4.7020108@oracle.com> References: <54E4A8EF.6090906@gmail.com> <54E6EBC4.7020108@oracle.com> Message-ID: <54E70133.7030207@gmail.com> HI Sundar - On 20/02/15 08:09, A. Sundararajan wrote: > * SyntaxError constructor accepting extra arguments apart from message > is not as per ECMAScript standard. That one is Firefox/Mozilla > specific extension. We try to *add* properties, functions for > extension - try not to modify/extend standard defined functions, > constructors. > > * User can fileName, lineNumber and columnNumber of constructed > SyntaxError instance. > > * On the java side, the NashornException and ScriptException's file, > line, column use the actual throw point from the script source. While > this can read the values from SyntaxError or any Error for that > matter, there is a problem. fileName, lineNumber, columnNumber could > be set to any value in script. These have to be converted to String, > int, int respectively. Conversion means calling [[DefaultValue]] with > String, Number hint - which is calling out to script code. This > process can itself throw exception!! All this may destroy info. on > where exactly the underlying exception was thrown. > > * There is clear workaround. Script code can always read SyntaxError > instance's fileName, lineNumber etc. - which can be set to anything > post construction. Java code can get underling ECMA error instance via > NashornException.getEcmaError - which would return a > ScriptObjectMirror. Java code can call > ScriptObjectMirror.getMember("fileName") etc. to retrieve properties > set by user's script. I've tried what you suggest, it seems to work (ish), but I end up with seriously grungy code that relies on casting and non public APIs that (I guess) could be changed without warning in any release, so I don't think I'd be happy doing this in Vert.x. Here's an example: (Yikes!) https://gist.github.com/purplefox/003fae1e32fd44368ffa So.... rewinding a bit here. The only reason I find myself shaving this particular Yak is because syntax errors thrown from evals() aren't reported by Nashorn with the fileName and lineNumber of the _eval_, instead they are reported with the fileName/lineNumber of where the eval was executed. I mentioned this in a previous post, but here is the gist again that demonstrates the issue: https://gist.github.com/purplefox/7ba0d87d2d1670b871a4 This means I have to manually catch SyntaxErrors in our require() implementation. Fill in the correct fileName, lineNumber etc and rethrow as new SyntaxError instances. But, as we discussed in this thread, that doesn't seem to work easily as I can't set fileName, lineNumber etc when constructing an instance in Nashorn, and if I set it afterwards those values aren't visible in Java (at least not in a portable way that doesn't rely on hacky reliance on non public APIs). If I don't do this, our users see a pretty useless error message when there's a syntax error in their module and it all leads to a very poor user experience. Imho, a better way to solve this would be for Nashorn to create syntax error instances when doing evals() that properly reflect the lineNumber and fileName of the _eval_ not of the place the eval was executed. This seems a far more intuitive way to do it and it would be consistent with the way other Error types are thrown from code in evals (e.g. TypeError, RangeError etc) which *do* reflect the correct line in the eval where the error occurred. Fundamentally a user is not going to care about the lineNumber where the eval was executed, they want to know where in the actual code the syntax error is - that's the useful information which is currently being obscured. So, any chance of changing/fixing the current behaviour? Doing that would mean I wouldn't have to little our code with piles of Yak hair trying to get the important information out of private classes, and I think it would lead to a better and more intuitive user experience :) > > Hope this helps, > -Sundar > > On Wednesday 18 February 2015 08:29 PM, Tim Fox wrote: >> Hi all, >> >> I've started a new thread for this, so as not to clutter the previous >> thread on exceptions. >> >> I've come across a possible issue with creating SyntaxError objects >> (and potentially other exceptions although I haven't tested them). >> >> https://gist.github.com/purplefox/dfe30a38098c1708e24b >> >> In the above gist I create a SyntaxError specifying message, >> fileName, and lineNumber. >> >> However fileName and lineNumber appear to be ignored, and instead the >> SyntaxError fileName and lineNumber are set to the fileName of the >> file where it was created and the lineNumber of the creation. >> >> I'm not sure if I'm doing something wrong, but according to >> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError >> I should be able to create SyntaxError objects like this. >> >> There appears to be a further issue. If I then throw the syntax error >> from the JS script, and catch it in Java like this: >> >> try { >> engine.eval(script); >> } catch (ScriptException e) { >> System.out.println("message:" + e.getMessage()); >> System.out.println("fileName:" + e.getFileName()); >> System.out.println("lineNumber:" + e.getLineNumber()); >> } >> >> Then the message, fileName and lineNumber always correspond to place >> where the object was created, not to the subsequently set values. >> >> In other words, I can't figure out a way of creating a SyntaxError >> object in JS with my own values of fileName and lineNumber and have >> those values available in Java when caught. >> >> Any ideas from the experts? :) >> >> > From sundararajan.athijegannathan at oracle.com Fri Feb 20 11:48:29 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Fri, 20 Feb 2015 17:18:29 +0530 Subject: Problems with SyntaxError construction In-Reply-To: <54E70133.7030207@gmail.com> References: <54E4A8EF.6090906@gmail.com> <54E6EBC4.7020108@oracle.com> <54E70133.7030207@gmail.com> Message-ID: <54E71F0D.6060904@oracle.com> Unlike TypeError or ReferenceError or any other execution error from eval'ed code, SyntaxError is thrown "up front". It is an "early error" as defined in "Clause 16" of ES 5.1 spec (https://es5.github.io/#x16). If we set evaluated code's file name and line number of syntax error, that would seem to imply that the execution reached that line and resulted in error. But, that is not the case here - execution of eval'ed code is yet to start. Error was detected during "compilation" and thrown from the "eval line" itself. Also, if there are nested eval calls and deepest one resulted in SyntaxError, we want to know which eval attempted to eval code with the syntax error. The "message" property of SyntaxError does contain the file and line (like file:N) of the eval-ed code that caused syntax error. -Sundar On Friday 20 February 2015 03:11 PM, Tim Fox wrote: > HI Sundar - > > On 20/02/15 08:09, A. Sundararajan wrote: >> * SyntaxError constructor accepting extra arguments apart from >> message is not as per ECMAScript standard. That one is >> Firefox/Mozilla specific extension. We try to *add* properties, >> functions for extension - try not to modify/extend standard defined >> functions, constructors. >> >> * User can fileName, lineNumber and columnNumber of constructed >> SyntaxError instance. >> >> * On the java side, the NashornException and ScriptException's file, >> line, column use the actual throw point from the script source. While >> this can read the values from SyntaxError or any Error for that >> matter, there is a problem. fileName, lineNumber, columnNumber could >> be set to any value in script. These have to be converted to String, >> int, int respectively. Conversion means calling [[DefaultValue]] with >> String, Number hint - which is calling out to script code. This >> process can itself throw exception!! All this may destroy info. on >> where exactly the underlying exception was thrown. >> >> * There is clear workaround. Script code can always read SyntaxError >> instance's fileName, lineNumber etc. - which can be set to anything >> post construction. Java code can get underling ECMA error instance >> via NashornException.getEcmaError - which would return a >> ScriptObjectMirror. Java code can call >> ScriptObjectMirror.getMember("fileName") etc. to retrieve properties >> set by user's script. > > I've tried what you suggest, it seems to work (ish), but I end up with > seriously grungy code that relies on casting and non public APIs that > (I guess) could be changed without warning in any release, so I don't > think I'd be happy doing this in Vert.x. Here's an example: > > (Yikes!) > > https://gist.github.com/purplefox/003fae1e32fd44368ffa > > So.... rewinding a bit here. The only reason I find myself shaving > this particular Yak is because syntax errors thrown from evals() > aren't reported by Nashorn with the fileName and lineNumber of the > _eval_, instead they are reported with the fileName/lineNumber of > where the eval was executed. > > I mentioned this in a previous post, but here is the gist again that > demonstrates the issue: > > https://gist.github.com/purplefox/7ba0d87d2d1670b871a4 > > This means I have to manually catch SyntaxErrors in our require() > implementation. Fill in the correct fileName, lineNumber etc and > rethrow as new SyntaxError instances. But, as we discussed in this > thread, that doesn't seem to work easily as I can't set fileName, > lineNumber etc when constructing an instance in Nashorn, and if I set > it afterwards those values aren't visible in Java (at least not in a > portable way that doesn't rely on hacky reliance on non public APIs). > If I don't do this, our users see a pretty useless error message when > there's a syntax error in their module and it all leads to a very poor > user experience. > > Imho, a better way to solve this would be for Nashorn to create syntax > error instances when doing evals() that properly reflect the > lineNumber and fileName of the _eval_ not of the place the eval was > executed. This seems a far more intuitive way to do it and it would be > consistent with the way other Error types are thrown from code in > evals (e.g. TypeError, RangeError etc) which *do* reflect the correct > line in the eval where the error occurred. Fundamentally a user is not > going to care about the lineNumber where the eval was executed, they > want to know where in the actual code the syntax error is - that's the > useful information which is currently being obscured. > > So, any chance of changing/fixing the current behaviour? Doing that > would mean I wouldn't have to little our code with piles of Yak hair > trying to get the important information out of private classes, and I > think it would lead to a better and more intuitive user experience :) > > > > > >> >> Hope this helps, >> -Sundar >> >> On Wednesday 18 February 2015 08:29 PM, Tim Fox wrote: >>> Hi all, >>> >>> I've started a new thread for this, so as not to clutter the >>> previous thread on exceptions. >>> >>> I've come across a possible issue with creating SyntaxError objects >>> (and potentially other exceptions although I haven't tested them). >>> >>> https://gist.github.com/purplefox/dfe30a38098c1708e24b >>> >>> In the above gist I create a SyntaxError specifying message, >>> fileName, and lineNumber. >>> >>> However fileName and lineNumber appear to be ignored, and instead >>> the SyntaxError fileName and lineNumber are set to the fileName of >>> the file where it was created and the lineNumber of the creation. >>> >>> I'm not sure if I'm doing something wrong, but according to >>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError >>> I should be able to create SyntaxError objects like this. >>> >>> There appears to be a further issue. If I then throw the syntax >>> error from the JS script, and catch it in Java like this: >>> >>> try { >>> engine.eval(script); >>> } catch (ScriptException e) { >>> System.out.println("message:" + e.getMessage()); >>> System.out.println("fileName:" + e.getFileName()); >>> System.out.println("lineNumber:" + e.getLineNumber()); >>> } >>> >>> Then the message, fileName and lineNumber always correspond to place >>> where the object was created, not to the subsequently set values. >>> >>> In other words, I can't figure out a way of creating a SyntaxError >>> object in JS with my own values of fileName and lineNumber and have >>> those values available in Java when caught. >>> >>> Any ideas from the experts? :) >>> >>> >> > From timvolpe at gmail.com Fri Feb 20 13:02:50 2015 From: timvolpe at gmail.com (Tim Fox) Date: Fri, 20 Feb 2015 13:02:50 +0000 Subject: Problems with SyntaxError construction In-Reply-To: <54E71F0D.6060904@oracle.com> References: <54E4A8EF.6090906@gmail.com> <54E6EBC4.7020108@oracle.com> <54E70133.7030207@gmail.com> <54E71F0D.6060904@oracle.com> Message-ID: <54E7307A.9010900@gmail.com> On 20/02/15 11:48, A. Sundararajan wrote: > Unlike TypeError or ReferenceError or any other execution error from > eval'ed code, SyntaxError is thrown "up front". It is an "early > error" as defined in "Clause 16" of ES 5.1 spec > (https://es5.github.io/#x16). If we set evaluated code's file name and > line number of syntax error, that would seem to imply that the > execution reached that line and resulted in error. But, that is not > the case here - execution of eval'ed code is yet to start. Error was > detected during "compilation" and thrown from the "eval line" itself. > Also, if there are nested eval calls and deepest one resulted in > SyntaxError, we want to know which eval attempted to eval code with > the syntax error. > > The "message" property of SyntaxError does contain the file I don't think it contains the correct fileName (as set by sourceURL), it always seems to be ""- I assume because the parsing fails before it reaches the sourceURL directive at the end of the eval'd scriptlet :( If I just pass the SyntaxError from Nashorn directly to the user it's highly confusing - they don't see a stack that points to their code (although it is there, buried two layers deep in an internal API - but surely we shouldn't expect users to navigate a non public API just to retrieve basic exception information) nor do they see the name of the script that caused the error (just ""), this makes it really hard for the user to fix their code. As discussed earlier it isn't an option for me to create my own SyntaxError instance with the useful values, as any values I set are ignored if thrown to Java code, without delving into a non public API to retrieve the JS values... So right now, I'm at a loss how I can make this work to give an acceptable user experience. I will keep hacking and see if I can come up with something... Thanks for your continuing help though :) > and line (like file:N) of the eval-ed code that caused syntax error. > > -Sundar > > On Friday 20 February 2015 03:11 PM, Tim Fox wrote: >> HI Sundar - >> >> On 20/02/15 08:09, A. Sundararajan wrote: >>> * SyntaxError constructor accepting extra arguments apart from >>> message is not as per ECMAScript standard. That one is >>> Firefox/Mozilla specific extension. We try to *add* properties, >>> functions for extension - try not to modify/extend standard defined >>> functions, constructors. >>> >>> * User can fileName, lineNumber and columnNumber of constructed >>> SyntaxError instance. >>> >>> * On the java side, the NashornException and ScriptException's file, >>> line, column use the actual throw point from the script source. >>> While this can read the values from SyntaxError or any Error for >>> that matter, there is a problem. fileName, lineNumber, columnNumber >>> could be set to any value in script. These have to be converted to >>> String, int, int respectively. Conversion means calling >>> [[DefaultValue]] with String, Number hint - which is calling out to >>> script code. This process can itself throw exception!! All this may >>> destroy info. on where exactly the underlying exception was thrown. >>> >>> * There is clear workaround. Script code can always read SyntaxError >>> instance's fileName, lineNumber etc. - which can be set to anything >>> post construction. Java code can get underling ECMA error instance >>> via NashornException.getEcmaError - which would return a >>> ScriptObjectMirror. Java code can call >>> ScriptObjectMirror.getMember("fileName") etc. to retrieve properties >>> set by user's script. >> >> I've tried what you suggest, it seems to work (ish), but I end up >> with seriously grungy code that relies on casting and non public APIs >> that (I guess) could be changed without warning in any release, so I >> don't think I'd be happy doing this in Vert.x. Here's an example: >> >> (Yikes!) >> >> https://gist.github.com/purplefox/003fae1e32fd44368ffa >> >> So.... rewinding a bit here. The only reason I find myself shaving >> this particular Yak is because syntax errors thrown from evals() >> aren't reported by Nashorn with the fileName and lineNumber of the >> _eval_, instead they are reported with the fileName/lineNumber of >> where the eval was executed. >> >> I mentioned this in a previous post, but here is the gist again that >> demonstrates the issue: >> >> https://gist.github.com/purplefox/7ba0d87d2d1670b871a4 >> >> This means I have to manually catch SyntaxErrors in our require() >> implementation. Fill in the correct fileName, lineNumber etc and >> rethrow as new SyntaxError instances. But, as we discussed in this >> thread, that doesn't seem to work easily as I can't set fileName, >> lineNumber etc when constructing an instance in Nashorn, and if I set >> it afterwards those values aren't visible in Java (at least not in a >> portable way that doesn't rely on hacky reliance on non public APIs). >> If I don't do this, our users see a pretty useless error message when >> there's a syntax error in their module and it all leads to a very >> poor user experience. >> >> Imho, a better way to solve this would be for Nashorn to create >> syntax error instances when doing evals() that properly reflect the >> lineNumber and fileName of the _eval_ not of the place the eval was >> executed. This seems a far more intuitive way to do it and it would >> be consistent with the way other Error types are thrown from code in >> evals (e.g. TypeError, RangeError etc) which *do* reflect the correct >> line in the eval where the error occurred. Fundamentally a user is >> not going to care about the lineNumber where the eval was executed, >> they want to know where in the actual code the syntax error is - >> that's the useful information which is currently being obscured. >> >> So, any chance of changing/fixing the current behaviour? Doing that >> would mean I wouldn't have to little our code with piles of Yak hair >> trying to get the important information out of private classes, and I >> think it would lead to a better and more intuitive user experience :) >> >> >> >> >> >>> >>> Hope this helps, >>> -Sundar >>> >>> On Wednesday 18 February 2015 08:29 PM, Tim Fox wrote: >>>> Hi all, >>>> >>>> I've started a new thread for this, so as not to clutter the >>>> previous thread on exceptions. >>>> >>>> I've come across a possible issue with creating SyntaxError objects >>>> (and potentially other exceptions although I haven't tested them). >>>> >>>> https://gist.github.com/purplefox/dfe30a38098c1708e24b >>>> >>>> In the above gist I create a SyntaxError specifying message, >>>> fileName, and lineNumber. >>>> >>>> However fileName and lineNumber appear to be ignored, and instead >>>> the SyntaxError fileName and lineNumber are set to the fileName of >>>> the file where it was created and the lineNumber of the creation. >>>> >>>> I'm not sure if I'm doing something wrong, but according to >>>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError >>>> I should be able to create SyntaxError objects like this. >>>> >>>> There appears to be a further issue. If I then throw the syntax >>>> error from the JS script, and catch it in Java like this: >>>> >>>> try { >>>> engine.eval(script); >>>> } catch (ScriptException e) { >>>> System.out.println("message:" + e.getMessage()); >>>> System.out.println("fileName:" + e.getFileName()); >>>> System.out.println("lineNumber:" + e.getLineNumber()); >>>> } >>>> >>>> Then the message, fileName and lineNumber always correspond to >>>> place where the object was created, not to the subsequently set >>>> values. >>>> >>>> In other words, I can't figure out a way of creating a SyntaxError >>>> object in JS with my own values of fileName and lineNumber and have >>>> those values available in Java when caught. >>>> >>>> Any ideas from the experts? :) >>>> >>>> >>> >> > From attila.szegedi at oracle.com Fri Feb 20 16:14:26 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Fri, 20 Feb 2015 17:14:26 +0100 Subject: Review request for JDK-8073560 Message-ID: <0018E8AE-6C79-412E-8ABD-EFBFBF37C89C@oracle.com> Please review JDK-8073560 at for Thanks, Attila. From sundararajan.athijegannathan at oracle.com Fri Feb 20 16:15:58 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Fri, 20 Feb 2015 21:45:58 +0530 Subject: Review request for JDK-8073560 In-Reply-To: <0018E8AE-6C79-412E-8ABD-EFBFBF37C89C@oracle.com> References: <0018E8AE-6C79-412E-8ABD-EFBFBF37C89C@oracle.com> Message-ID: <54E75DBE.6080102@oracle.com> +1 On Friday 20 February 2015 09:44 PM, Attila Szegedi wrote: > Please review JDK-8073560 at for > > Thanks, > Attila. From james.laskey at oracle.com Fri Feb 20 16:23:24 2015 From: james.laskey at oracle.com (Jim Laskey (Oracle)) Date: Fri, 20 Feb 2015 12:23:24 -0400 Subject: Review request for JDK-8073560 In-Reply-To: <0018E8AE-6C79-412E-8ABD-EFBFBF37C89C@oracle.com> References: <0018E8AE-6C79-412E-8ABD-EFBFBF37C89C@oracle.com> Message-ID: <46416FC0-F671-4E4B-ADB7-2E984E719699@oracle.com> +1 On Feb 20, 2015, at 12:14 PM, Attila Szegedi wrote: > Please review JDK-8073560 at for > > Thanks, > Attila. From anthony.vanelverdinghe at gmail.com Sun Feb 22 11:12:09 2015 From: anthony.vanelverdinghe at gmail.com (Anthony Vanelverdinghe) Date: Sun, 22 Feb 2015 12:12:09 +0100 Subject: Unintuitive here document behavior: bug or feature? Message-ID: <54E9B989.3020604@gmail.com> Hi When using a here document, statements that are on the same line as the initial < Hi How can I avoid string interpolation in here documents with Nashorn? In other words: what if the here document contains the literal string "${a}"? The user guide section on here documents [1] doesn't tell how to do this. If this is not available yet, shall I create a bug report for this? Kind regards, Anthony [1] http://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/shell.html#sthref26 From sundararajan.athijegannathan at oracle.com Mon Feb 23 03:46:49 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Mon, 23 Feb 2015 09:16:49 +0530 Subject: Unintuitive here document behavior: bug or feature? In-Reply-To: <54E9B989.3020604@gmail.com> References: <54E9B989.3020604@gmail.com> Message-ID: <54EAA2A9.3030107@oracle.com> Hi, It appears to be a bug to me. Thanks for reporting. I filed https://bugs.openjdk.java.net/browse/JDK-8073612 Thanks, -Sundar On Sunday 22 February 2015 04:42 PM, Anthony Vanelverdinghe wrote: > Hi > > When using a here document, statements that are on the same line as > the initial < "heredoc statement". Is this a bug or a feature? > > For example: > > var a = 2; > print(< a++; > ${a} > EOD > print(a); > > prints > > a++; > 2 > here > 3 > > Kind regards, Anthony From sundararajan.athijegannathan at oracle.com Mon Feb 23 04:03:06 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Mon, 23 Feb 2015 09:33:06 +0530 Subject: Here documents: how to avoid string interpolation? In-Reply-To: <54E9BD06.8050301@gmail.com> References: <54E9BD06.8050301@gmail.com> Message-ID: <54EAA67A.80504@oracle.com> Hi, The following seems to work (based on code reading + testing): var str = "hello"; var s = "$\{str} world"; print(s); // prints ${str} world var s1 = "${str} world"; print(s1) // prints "hello world" Still, I've filed a bug to clarify and document expected, supported behaviour. https://bugs.openjdk.java.net/browse/JDK-8073613 Thanks, -Sundar On Sunday 22 February 2015 04:57 PM, Anthony Vanelverdinghe wrote: > Hi > > How can I avoid string interpolation in here documents with Nashorn? > In other words: what if the here document contains the literal string > "${a}"? The user guide section on here documents [1] doesn't tell how > to do this. > If this is not available yet, shall I create a bug report for this? > > Kind regards, Anthony > > [1] > http://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/shell.html#sthref26 From james.laskey at oracle.com Mon Feb 23 12:54:23 2015 From: james.laskey at oracle.com (Jim Laskey (Oracle)) Date: Mon, 23 Feb 2015 08:54:23 -0400 Subject: Unintuitive here document behavior: bug or feature? In-Reply-To: <54E9B989.3020604@gmail.com> References: <54E9B989.3020604@gmail.com> Message-ID: Feature - the heredoc doesn't begin until the next line (multi-LINE string.) This makes the JS code visually clearer. -- Jim On Feb 22, 2015, at 7:12 AM, Anthony Vanelverdinghe wrote: > Hi > > When using a here document, statements that are on the same line as the initial < > For example: > > var a = 2; > print(< a++; > ${a} > EOD > print(a); > > prints > > a++; > 2 > here > 3 > > Kind regards, Anthony From attila.szegedi at oracle.com Mon Feb 23 14:59:00 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Mon, 23 Feb 2015 15:59:00 +0100 Subject: Review request for JDK-8035712 Message-ID: Please review JDK-8035712 at for This change restores some of the pre-static analysis (and pre-optimistic typing) RuntimeCallSite specialization functionality, without actually using RuntimeCallSite. Basically, equality and relational operators where one operand is a number (or boolean for less-than and friends) and the other is an object are executed more efficiently, by weakening the object operand to a number. Previously, this was compiled to boxing the number and using generic ScriptRuntime.EQ, LT, etc. Thanks, Attila. From sundararajan.athijegannathan at oracle.com Mon Feb 23 16:10:52 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Mon, 23 Feb 2015 21:40:52 +0530 Subject: How to extend a Java interface or class with overloaded methods using Nashorn? Message-ID: <54EB510C.2010802@oracle.com> Hi Christopher, http://mail.openjdk.java.net/pipermail/nashorn-dev/2015-February/004178.html Somehow missed responding to this email. Yes, you can implement interface with overloaded methods. You can use arguments inside the implementing function to differentiate. var Foo = Java.type('bar.Foo'); var instance = new Foo { bar: function(){ print(arguments.length); for (i in arguments) print(arguments[i]); } }; instance.bar(); instance.bar(223); instance.bar("hello"); Hope this helps, -Sundar From anthony.vanelverdinghe at gmail.com Mon Feb 23 18:50:46 2015 From: anthony.vanelverdinghe at gmail.com (Anthony Vanelverdinghe) Date: Mon, 23 Feb 2015 19:50:46 +0100 Subject: Unintuitive here document behavior: bug or feature? In-Reply-To: <54EAA2A9.3030107@oracle.com> References: <54E9B989.3020604@gmail.com> <54EAA2A9.3030107@oracle.com> Message-ID: <54EB7686.5030506@gmail.com> Hi I see the bug has been resolved as not an issue. However, in my opinion this behavior is sufficiently unintuitive that it should at least be documented: - as far as I know, appending commands after the starting "< Hi, > > It appears to be a bug to me. Thanks for reporting. I filed > https://bugs.openjdk.java.net/browse/JDK-8073612 > > Thanks, > -Sundar > > On Sunday 22 February 2015 04:42 PM, Anthony Vanelverdinghe wrote: >> Hi >> >> When using a here document, statements that are on the same line as >> the initial <> "heredoc statement". Is this a bug or a feature? >> >> For example: >> >> var a = 2; >> print(<> a++; >> ${a} >> EOD >> print(a); >> >> prints >> >> a++; >> 2 >> here >> 3 >> >> Kind regards, Anthony > > From james.laskey at oracle.com Mon Feb 23 19:24:20 2015 From: james.laskey at oracle.com (Jim Laskey (Oracle)) Date: Mon, 23 Feb 2015 15:24:20 -0400 Subject: Unintuitive here document behavior: bug or feature? In-Reply-To: <54EB7686.5030506@gmail.com> References: <54E9B989.3020604@gmail.com> <54EAA2A9.3030107@oracle.com> <54EB7686.5030506@gmail.com> Message-ID: <1BC813B2-4E28-43D6-97CD-A39588EEB8E2@oracle.com> Revising the document is in the works. Cheers, -- Jim On Feb 23, 2015, at 2:50 PM, Anthony Vanelverdinghe wrote: > Hi > > I see the bug has been resolved as not an issue. However, in my opinion this behavior is sufficiently unintuitive that it should at least be documented: > - as far as I know, appending commands after the starting "< - moreover, users that are unaware of this behavior, may start writing text on the same line & will get errors at runtime. For example: > > print(< And this is line 2. > EOD > > results in: > > test.js:3:-33 Expected ; but found is > print(< ^ > > and: > > print(< And this is line 2. > EOD > > results in: > > And this is line 2. > test.js:3 ReferenceError: "This" is not defined > > (also note that the error refers to line 3 in both cases, even though line 3 just contains the closing delimiter) > > So in conclusion, I would like to ask for this bug to be reopened, with the goal to specify this behavior in the appropriate section of the Nashorn user guide [1]. Thanks in advance for your consideration. > > Kind regards, Anthony > > [1] http://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/shell.html#sthref26 > > > On 23/02/2015 4:46, A. Sundararajan wrote: >> Hi, >> >> It appears to be a bug to me. Thanks for reporting. I filed https://bugs.openjdk.java.net/browse/JDK-8073612 >> >> Thanks, >> -Sundar >> >> On Sunday 22 February 2015 04:42 PM, Anthony Vanelverdinghe wrote: >>> Hi >>> >>> When using a here document, statements that are on the same line as the initial <>> >>> For example: >>> >>> var a = 2; >>> print(<>> a++; >>> ${a} >>> EOD >>> print(a); >>> >>> prints >>> >>> a++; >>> 2 >>> here >>> 3 >>> >>> Kind regards, Anthony >> >> > From anthony.vanelverdinghe at gmail.com Mon Feb 23 19:30:30 2015 From: anthony.vanelverdinghe at gmail.com (Anthony Vanelverdinghe) Date: Mon, 23 Feb 2015 20:30:30 +0100 Subject: Here documents: how to avoid string interpolation? In-Reply-To: <54EAA67A.80504@oracle.com> References: <54E9BD06.8050301@gmail.com> <54EAA67A.80504@oracle.com> Message-ID: <54EB7FD6.7060306@gmail.com> Hi In other languages (e.g. Bash [1], PHP [2], Ruby, Perl), this is typically solved by quoting the delimiter string at the start of the here document [3]. So I would like to propose this approach for Nashorn as well. Note that some, like Bash and PHP, treat double quotes the same as single quotes (i.e. interpolation is disabled), whereas others, like Ruby and Perl, treat double quotes the same as no quotes (i.e. interpolation is enabled). Personally, I'm strongly in favor of the Bash/PHP approach to avoid confusion. So: var a = 4; var b = 2; print(< Hi, > > The following seems to work (based on code reading + testing): > > var str = "hello"; > var s = "$\{str} world"; > print(s); // prints ${str} world > var s1 = "${str} world"; > print(s1) // prints "hello world" > > Still, I've filed a bug to clarify and document expected, supported > behaviour. > > https://bugs.openjdk.java.net/browse/JDK-8073613 > > Thanks, > -Sundar > > On Sunday 22 February 2015 04:57 PM, Anthony Vanelverdinghe wrote: >> Hi >> >> How can I avoid string interpolation in here documents with Nashorn? >> In other words: what if the here document contains the literal string >> "${a}"? The user guide section on here documents [1] doesn't tell how >> to do this. >> If this is not available yet, shall I create a bug report for this? >> >> Kind regards, Anthony >> >> [1] >> http://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/shell.html#sthref26 > > From sundararajan.athijegannathan at oracle.com Tue Feb 24 02:21:53 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Tue, 24 Feb 2015 07:51:53 +0530 Subject: Unintuitive here document behavior: bug or feature? In-Reply-To: <54EB7686.5030506@gmail.com> References: <54E9B989.3020604@gmail.com> <54EAA2A9.3030107@oracle.com> <54EB7686.5030506@gmail.com> Message-ID: <54EBE041.9080801@oracle.com> We do plan to update the documentation. Another separate bug will be filed for doc issue(s) in this area. Thanks, -Sundar On Tuesday 24 February 2015 12:20 AM, Anthony Vanelverdinghe wrote: > Hi > > I see the bug has been resolved as not an issue. However, in my > opinion this behavior is sufficiently unintuitive that it should at > least be documented: > - as far as I know, appending commands after the starting "< not possible in a bash script (already the fact that in Nashorn the > "< is pretty unique, I believe) > - moreover, users that are unaware of this behavior, may start writing > text on the same line & will get errors at runtime. For example: > > print(< And this is line 2. > EOD > > results in: > > test.js:3:-33 Expected ; but found is > print(< ^ > > and: > > print(< And this is line 2. > EOD > > results in: > > And this is line 2. > test.js:3 ReferenceError: "This" is not defined > > (also note that the error refers to line 3 in both cases, even though > line 3 just contains the closing delimiter) > > So in conclusion, I would like to ask for this bug to be reopened, > with the goal to specify this behavior in the appropriate section of > the Nashorn user guide [1]. Thanks in advance for your consideration. > > Kind regards, Anthony > > [1] > http://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/shell.html#sthref26 > > > On 23/02/2015 4:46, A. Sundararajan wrote: >> Hi, >> >> It appears to be a bug to me. Thanks for reporting. I filed >> https://bugs.openjdk.java.net/browse/JDK-8073612 >> >> Thanks, >> -Sundar >> >> On Sunday 22 February 2015 04:42 PM, Anthony Vanelverdinghe wrote: >>> Hi >>> >>> When using a here document, statements that are on the same line as >>> the initial <>> "heredoc statement". Is this a bug or a feature? >>> >>> For example: >>> >>> var a = 2; >>> print(<>> a++; >>> ${a} >>> EOD >>> print(a); >>> >>> prints >>> >>> a++; >>> 2 >>> here >>> 3 >>> >>> Kind regards, Anthony >> >> > From sundararajan.athijegannathan at oracle.com Tue Feb 24 09:34:02 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Tue, 24 Feb 2015 15:04:02 +0530 Subject: RFR 8073707: const re-assignment should not reported as a "early error" Message-ID: <54EC458A.7060309@oracle.com> Please review http://cr.openjdk.java.net/~sundar/8073707/ for https://bugs.openjdk.java.net/browse/JDK-8073707 Thanks, -Sundar From hannes.wallnoefer at oracle.com Tue Feb 24 10:08:08 2015 From: hannes.wallnoefer at oracle.com (Hannes Wallnoefer) Date: Tue, 24 Feb 2015 11:08:08 +0100 Subject: RFR 8073707: const re-assignment should not reported as a "early error" In-Reply-To: <54EC458A.7060309@oracle.com> References: <54EC458A.7060309@oracle.com> Message-ID: <54EC4D88.4040503@oracle.com> The fix is incomplete as it does not substitute early error checks with runtime checks for local (non-scope) symbols. This also exposes a gap in our tests regarding non-scope const. I'm assigning the bug to myself to add the missing check and tests. Hannes Am 2015-02-24 um 10:34 schrieb A. Sundararajan: > Please review http://cr.openjdk.java.net/~sundar/8073707/ for > https://bugs.openjdk.java.net/browse/JDK-8073707 > > Thanks, > -Sundar From sundararajan.athijegannathan at oracle.com Tue Feb 24 10:09:23 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Tue, 24 Feb 2015 15:39:23 +0530 Subject: RFR 8073707: const re-assignment should not reported as a "early error" In-Reply-To: <54EC4D88.4040503@oracle.com> References: <54EC458A.7060309@oracle.com> <54EC4D88.4040503@oracle.com> Message-ID: <54EC4DD3.8080704@oracle.com> Okay, thanks. It would be better if we separate early errors tests from runtime errors. Perhaps test/script/error/es6 directory for early-error scripts.. -Sundar On Tuesday 24 February 2015 03:38 PM, Hannes Wallnoefer wrote: > The fix is incomplete as it does not substitute early error checks > with runtime checks for local (non-scope) symbols. > > This also exposes a gap in our tests regarding non-scope const. I'm > assigning the bug to myself to add the missing check and tests. > > Hannes > > Am 2015-02-24 um 10:34 schrieb A. Sundararajan: >> Please review http://cr.openjdk.java.net/~sundar/8073707/ for >> https://bugs.openjdk.java.net/browse/JDK-8073707 >> >> Thanks, >> -Sundar > From marcus.lagergren at oracle.com Tue Feb 24 10:28:18 2015 From: marcus.lagergren at oracle.com (Marcus Lagergren) Date: Tue, 24 Feb 2015 11:28:18 +0100 Subject: RFR 8073707: const re-assignment should not reported as a "early error" In-Reply-To: <54EC4DD3.8080704@oracle.com> References: <54EC458A.7060309@oracle.com> <54EC4D88.4040503@oracle.com> <54EC4DD3.8080704@oracle.com> Message-ID: +1 with this. /M > On 24 Feb 2015, at 11:09, A. Sundararajan wrote: > > Okay, thanks. > > It would be better if we separate early errors tests from runtime errors. Perhaps test/script/error/es6 directory for early-error scripts.. > > -Sundar > > On Tuesday 24 February 2015 03:38 PM, Hannes Wallnoefer wrote: >> The fix is incomplete as it does not substitute early error checks with runtime checks for local (non-scope) symbols. >> >> This also exposes a gap in our tests regarding non-scope const. I'm assigning the bug to myself to add the missing check and tests. >> >> Hannes >> >> Am 2015-02-24 um 10:34 schrieb A. Sundararajan: >>> Please review http://cr.openjdk.java.net/~sundar/8073707/ for https://bugs.openjdk.java.net/browse/JDK-8073707 >>> >>> Thanks, >>> -Sundar >> > From sundararajan.athijegannathan at oracle.com Fri Feb 27 11:31:04 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Fri, 27 Feb 2015 17:01:04 +0530 Subject: RFR 8074021: Indirect eval fails when used as an element of an array or as a property of an object Message-ID: <54F05578.3050304@oracle.com> Please review http://cr.openjdk.java.net/~sundar/8074021/ for https://bugs.openjdk.java.net/browse/JDK-8074021 -Sundar From hannes.wallnoefer at oracle.com Fri Feb 27 11:52:34 2015 From: hannes.wallnoefer at oracle.com (Hannes Wallnoefer) Date: Fri, 27 Feb 2015 12:52:34 +0100 Subject: RFR 8074021: Indirect eval fails when used as an element of an array or as a property of an object In-Reply-To: <54F05578.3050304@oracle.com> References: <54F05578.3050304@oracle.com> Message-ID: <54F05A82.7050907@oracle.com> +1 Am 2015-02-27 um 12:31 schrieb A. Sundararajan: > Please review http://cr.openjdk.java.net/~sundar/8074021/ for > https://bugs.openjdk.java.net/browse/JDK-8074021 > > -Sundar From hannes.wallnoefer at oracle.com Fri Feb 27 12:26:05 2015 From: hannes.wallnoefer at oracle.com (Hannes Wallnoefer) Date: Fri, 27 Feb 2015 13:26:05 +0100 Subject: Review request for JDK-8073707: const re-assignment should not reported as a early error Message-ID: <54F0625D.1030600@oracle.com> Please review JDK-8073707: const re-assignment should not reported as a early error: http://cr.openjdk.java.net/~hannesw/8073707/ This is Sundar's patch from two days ago with added runtime checks in codegen. I also rewrote the test, taking advantage of the fact that const reassignment no longer causes a SyntaxError. Thanks, Hannes From sundararajan.athijegannathan at oracle.com Fri Feb 27 12:30:23 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Fri, 27 Feb 2015 18:00:23 +0530 Subject: Review request for JDK-8073707: const re-assignment should not reported as a early error In-Reply-To: <54F0625D.1030600@oracle.com> References: <54F0625D.1030600@oracle.com> Message-ID: <54F0635F.1020308@oracle.com> +1 On Friday 27 February 2015 05:56 PM, Hannes Wallnoefer wrote: > Please review JDK-8073707: const re-assignment should not reported as > a early error: > > http://cr.openjdk.java.net/~hannesw/8073707/ > > This is Sundar's patch from two days ago with added runtime checks in > codegen. I also rewrote the test, taking advantage of the fact that > const reassignment no longer causes a SyntaxError. > > Thanks, > Hannes From attila.szegedi at oracle.com Fri Feb 27 12:40:25 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Fri, 27 Feb 2015 13:40:25 +0100 Subject: Review request for JDK-8073707: const re-assignment should not reported as a early error In-Reply-To: <54F0625D.1030600@oracle.com> References: <54F0625D.1030600@oracle.com> Message-ID: <8D31C0FB-4CEF-4EB7-9342-74FA91A12368@oracle.com> +1 On Feb 27, 2015, at 1:26 PM, Hannes Wallnoefer wrote: > Please review JDK-8073707: const re-assignment should not reported as a early error: > > http://cr.openjdk.java.net/~hannesw/8073707/ > > This is Sundar's patch from two days ago with added runtime checks in codegen. I also rewrote the test, taking advantage of the fact that const reassignment no longer causes a SyntaxError. > > Thanks, > Hannes From attila.szegedi at oracle.com Fri Feb 27 12:40:32 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Fri, 27 Feb 2015 13:40:32 +0100 Subject: RFR 8074021: Indirect eval fails when used as an element of an array or as a property of an object In-Reply-To: <54F05578.3050304@oracle.com> References: <54F05578.3050304@oracle.com> Message-ID: <948FC8FA-CBB6-4513-B001-3334FD63EBCB@oracle.com> +1 On Feb 27, 2015, at 12:31 PM, A. Sundararajan wrote: > Please review http://cr.openjdk.java.net/~sundar/8074021/ for https://bugs.openjdk.java.net/browse/JDK-8074021 > > -Sundar From fc86 at outlook.fr Fri Feb 27 13:15:25 2015 From: fc86 at outlook.fr (=?iso-8859-1?B?Q2zpbWVudCBGYXVjb25uaWVy?=) Date: Fri, 27 Feb 2015 14:15:25 +0100 Subject: nashorn's engine debugging API Message-ID: Following the discussion started on Twitter, I would like to have more details about this API you talked about. I started doing the exactly same thing adapting JVMDI tty to my needs but it was too complicated so I change my approach before viewing how to interact with nashorn "compiled" js. So, I'm really interested to your example. Thanks in advance for your reply. Cl?ment Fauconnier. From fc86 at outlook.fr Fri Feb 27 13:18:31 2015 From: fc86 at outlook.fr (=?iso-8859-1?B?Q2zpbWVudCBGYXVjb25uaWVy?=) Date: Fri, 27 Feb 2015 14:18:31 +0100 Subject: nashorn's engine debugging API In-Reply-To: References: Message-ID: Dear Jim Laskey Following the discussion started on Twitter, I would like to have more details about this API you talked about.I started doing the exactly same thing adapting JVMDI tty to my needs but it was too complicated so I change my approach before viewing how to interact with nashorn "compiled" js. So, I'm really interested to your example. Thanks in advance for your reply. Cl?ment Fauconnier. From danbaryak at gmail.com Tue Feb 10 13:25:13 2015 From: danbaryak at gmail.com (Dan Bar-Yaakov) Date: Tue, 10 Feb 2015 13:25:13 -0000 Subject: Help with compiling TypeScript using nashorn Message-ID: Hi Marcus, thanks for the reply in LinkedIn. following that, here is a brief description of what I'm trying to do: I work for Luminis Technologies. We build open source components for building modular web applications using OSGi (The Amdatu Project). We would like to add some components that automatically compile frontend resources written in multiple languages (typescript, coffeescript, lescss, sass etc.). As the first stage we would like to get typescript working, as it's common in many projects that use our stack. Since we want to do it automatically on each change, speed is critical. That's why I was very glad to learn about your latest nashorn performance enhancements. To get started I've tried compiling the microsoft TypeScript distribution (using Jake) and running it using jjs as I've seen in some examples online (j*js tsc.js --optimistic-types=true -- hello.ts* for example) and got the following error: tsc.js:20361 TypeError: Cannot read property "args" from undefined got the same thing when trying in Java code. If it is indeed already possible to compile TS using nashorn, I'd really appreciate any help you can provide on how to do so. Many thanks, Dan From james.laskey at oracle.com Fri Feb 27 13:33:19 2015 From: james.laskey at oracle.com (Jim Laskey (Oracle)) Date: Fri, 27 Feb 2015 09:33:19 -0400 Subject: nashorn's engine debugging API In-Reply-To: References: Message-ID: Cl?ment, I did a demo at JavaOne in 2013 using Nashorn to debug Nashorn. The app was called Askari, after the birds you see picking bugs off the backs of rhinoceros. -------------- next part -------------- cd .../askari/src jjs -cp ../lib/tools.jar -scripting -fx askari.js You should be able to load a small script (use open door), set breakpoints (click on dimmed stop sign), step and view values. Cheers, -- Jim > On Feb 27, 2015, at 9:18 AM, Cl?ment Fauconnier wrote: > > Dear Jim Laskey > Following the discussion started on Twitter, I would like to have more details about this API you talked about.I started doing the exactly same thing adapting JVMDI tty to my needs but it was too complicated so I change my approach before viewing how to interact with nashorn "compiled" js. > So, I'm really interested to your example. > > Thanks in advance for your reply. > Cl?ment Fauconnier. From attila.szegedi at oracle.com Fri Feb 27 14:29:48 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Fri, 27 Feb 2015 15:29:48 +0100 Subject: Review request for JDK-8074031 Message-ID: Please review JDK-8074031 at for Thanks, Attila. From hannes.wallnoefer at oracle.com Fri Feb 27 14:36:01 2015 From: hannes.wallnoefer at oracle.com (Hannes Wallnoefer) Date: Fri, 27 Feb 2015 15:36:01 +0100 Subject: Review request for JDK-8074031 In-Reply-To: References: Message-ID: <54F080D1.9020501@oracle.com> +1 Am 2015-02-27 um 15:29 schrieb Attila Szegedi: > Please review JDK-8074031 at for > > Thanks, > Attila. From marcus.lagergren at oracle.com Fri Feb 27 16:06:20 2015 From: marcus.lagergren at oracle.com (Marcus Lagergren) Date: Fri, 27 Feb 2015 17:06:20 +0100 Subject: Review request for JDK-8074031 In-Reply-To: References: Message-ID: <571887C7-5B8D-4E84-BC38-BE7793BA408C@oracle.com> +1 > On 27 Feb 2015, at 15:29, Attila Szegedi wrote: > > Please review JDK-8074031 at for > > Thanks, > Attila.