Thanks! On Tuesday, May 17, 2016, Sundararajan Athijegannathan < sundararajan.athijegannat...@oracle.com> wrote:
> Hi, > > Filed a bug: https://bugs.openjdk.java.net/browse/JDK-8157160 > > Thanks, > > -Sundar > > On 5/13/2016 8:16 PM, Eric Pederson wrote: > > Hi Sundar - > > It would be helpful for sure. We use JSON for serialization and debugging > a lot. Also if it worked it could simplify our custom ScriptObjectMirror > -> native object conversion logic from 30 lines down to > JSON.parse(JSON.stringify(scriptObjMirror)) :). > > Besides the JSON stuff our biggest problem has been ScriptObjectMirrors > being treated like regular objects and passed down call chains and then > either throwing exceptions or silently failing and it's hard to figure out > why. Junior developers get completely baffled. We have solved the problem > with the commonjs/require loading pattern on the script loading side and > the proxy pattern on the Java calling side. It would be nice to have > official solutions for these but it's not urgent. It might be something > worth adding to the documentation. > > Thanks, > > > > -- Eric > > On Fri, May 13, 2016 at 12:30 AM, Sundararajan Athijegannathan < > <javascript:_e(%7B%7D,'cvml','sundararajan.athijegannat...@oracle.com');> > sundararajan.athijegannat...@oracle.com > <javascript:_e(%7B%7D,'cvml','sundararajan.athijegannat...@oracle.com');>> > wrote: > >> Hi Eric, >> >> That commonjs/require loading pattern is not bad [wrapping eval'ed code >> inside a function]. If your loaded scripts are (somewhat) well-behaved, it >> does solve the problem of global namespace pollution. >> >> Yes, ScriptObjectMirrors are not uniformly treated like ScriptObject >> everywhere. But, I'm not sure how far we can fix that :( Is JSON handling >> (w.r.t ScriptObjectMirror) your main pain point? We *may* be able to >> address that. >> >> Thanks, >> >> -Sundar >> >> On 5/12/2016 11:10 PM, Eric Pederson wrote: >> >> Hi Sundar: >> >> 1. I investigated loadWithNewGlobal because it looked promising for this >> use case. Say you use loadWithNewGlobal to load a function. If you >> call the loaded function and it returns an object or array the caller gets >> a ScriptObjectMirror. The problems with a ScriptObjectMirror "object" >> are: >> >> - Cannot call Object methods like keys or getOwnPropertyNames. You >> get an exception: TypeError: cannot call undefined. To iterate over >> the properties you must use a for in loop. >> - Cannot convert ScriptObjectMirror to JSON using JSON.stringify. It >> returns undefined. >> >> If the function loaded with loadWithNewGlobal returns an array then >> things are better. Interestingly you can call most Array methods (like >> forEach and map) on a ScriptObjectMirror "array". But JSON.stringify also >> returns undefined. >> >> I did find one issue with an array returned by a loadWithNewGlobal >> loaded function - calling sort with a comparator. For example, if the >> loaded function returned testArray, a ScriptObjectMirror "array": >> >> *var **sorted *= *testArray*.sort(*function*(a, b) { >> >> *return *a - b; >> }); >> >> >> >> throws an exception*: *TypeError: function(a, b) { return a - b; } is >> not a function. >> >> >> These were the same "mutant" issues that we also saw with JSObjects >> returned by Java methods. >> >> >> The hack that we are using now to load code without effecting the global >> namespace is the same one discussed in this thread: >> >> <http://thread.gmane.org/gmane.comp.java.openjdk.nashorn.devel/1722> >> http://thread.gmane.org/gmane.comp.java.openjdk.nashorn.devel/1722. >> >> >> The code that we are using is copied/adapted from Vertx (thanks, Tim!): >> >> >> function loadEval(path) { >> >> *var *dir = *new **File*(path).getParent(); >> >> *var *body = *readFile*(path); >> >> *var *moduleFunc = >> >> *"function(exports, module, require, __filename, __dirname){" *+ >> body + *"**\n**}**\n**//# sourceURL=" *+ path; >> >> >> *try {* >> >> *var *func = eval(moduleFunc); >> >> } *catch *(ex) { >> >> *if *(ex *instanceof **SyntaxError*) { >> >> >> *// WARNING! Large pile of Yak hair ahead! * >> >> *var *ne = ex.nashornException; >> >> *var *cause = ne.cause; >> >> *var *msg = cause.message.replace(*"<eval>"*, file); >> >> *var *lineNumber = cause.*lineNumber;* >> >> console.log(*"ERROR: " *+ msg + *" in file " *+ file + *" at >> line " *+ lineNumber); >> } >> >> *throw *ex; >> } >> >> *var *module = { *exports*: {} }; >> >> func(module.*exports*, module, require, path, dir); >> >> *return *module.*exports*; >> >> } >> >> >> This seems like a hack to me - but I'm coming from the Java world so this >> may be par for the course in Javascript-land :) Hack or no, it is the >> best of both worlds: it does not change the global namespace, yet the code >> that it returns lives in the global context, so if you call a loaded >> function it will return a native object, not a ScriptObjectMirror. >> >> >> We'd like to have a built-in equivalent of this loadEval function. It >> doesn't need to use those specific arguments (export, module, etc), but >> you must be able to pass arguments in to provide a context to the loaded >> code. >> >> >> Alternatively if you could make ScriptObjectMirrors 100% compatible with >> native objects that would work too. Then we could use loadWithNewGlobal. >> >> >> 2. The problem that we are having with objects returned by Java methods >> is the same as what I described above because the returned JSObjects are >> seen as ScriptObjectMirrors by the calling Javascript code. >> >> >> What we are doing now is wrapping each Java object with a Javascript >> proxy. When you call the proxy it calls the corresponding Java method, >> then converts the returned ScriptObjectMirror into a native JS object >> using a custom conversion function. >> >> >> What would be nice for this use case is a standard function to convert >> ScriptObjectMirrors to native JS objects (what I was calling asJSONCompatible >> below). Or if ScriptObjectMirrors were 100% compatible that would be >> even better - we could get rid of our JS proxy objects. >> >> >> I'm happy to file some enhancement requests. Though it seems like the >> bug trackers are read-only to the general public though, how would I get >> access? >> >> >> Thanks, >> >> >> -- Eric >> >> On Thu, May 12, 2016 at 12:36 AM, Sundararajan Athijegannathan < >> sundararajan.athijegannat...@oracle.com >> <javascript:_e(%7B%7D,'cvml','sundararajan.athijegannat...@oracle.com');> >> > wrote: >> >>> Hi, >>> >>> Thanks for your comments! >>> >>> Making comments on forthcoming JDK releases is hard :) Whatever I'm >>> saying now, may not happen - the usual disclaimer applies. >>> >>> No, we expect that only a subset of ES6 features will be implemented for >>> Java 9. >>> >>> 1. On loading definitions without changing global namespace: you meant >>> current global namespace? loadWithNewGlobal creates a new global and >>> loads definitions into that. >>> >>> Would that be useful for you? or anything else? Which hack you're >>> referring to? Please file an enhancement with your requirements. >>> >>> 2. on JSON: Again, will you please provide a simple test case and/or >>> file an enhancement with requirements? >>> >>> Thanks, >>> -Sundar >>> >>> On 5/12/2016 12:56 AM, Eric Pederson wrote: >>> > I've been noticing the Java 9 ES6 features tweeted by @sundararajan_a >>> > <https://twitter.com/sundararajan_a>. Looks awesome! Will there be >>> full >>> > ES6 support in Java 9? >>> > >>> > There are a couple of other things we would love to see in the updated >>> > Nashorn: >>> > >>> > 1. We've been using the same hack that you recommended to Tim Fox for >>> > loading functions without changing the global namespace - the Avatar/js >>> > CommonJS/require hack. It would be great if this was supported >>> natively in >>> > Nashorn via a new loadXXX(). >>> > >>> > 2. It would be also be great to have the inverse of asJSONCompatible >>> for a) >>> > JSObjects returned by Java code and b) objects from other scopes. Our >>> name >>> > for ScriptObjectMirrors in Javascript code is "mutant objects": they >>> look >>> > like regular JS objects but they are missing most of their DNA, and you >>> > don't realize until you get an exception or silent failure somewhere >>> down >>> > the call chain where it's difficult to figure out why :) >>> > >>> > Anyway, the upcoming stuff looks great! >>> > >>> > Thanks, >>> > >>> > -- Eric >>> >>> >> >> > > -- Sent from Gmail Mobile