Programmering

Nashorn: JavaScript ble bra i Java 8

Nashorn, uttalt "nass-horn", er tysk for "neshorn", og det er et av dyrenavnene til en tysk tankjager som ble brukt i andre verdenskrig. Det er også navnet på erstatningen - introdusert med Java 8 - for den gamle, sakte Rhino JavaScript-motoren. Både Rhino og Nashorn er implementeringer av JavaScript-språket som er skrevet for å kjøre på den virtuelle Java-maskinen, eller JVM.

Obligatorisk rant: JavaScript kan ha Java som en del av navnet, men de to språkene er veldig forskjellige i ånd og design, så vel som i implementeringene. Likevel er en måte å implementere en JavaScript-tolk på å kompilere JavaScript i Java-byte-koder, det er det Rhino og Nashorn ble designet for å gjøre.

Du tenker sannsynligvis på JavaScript når det gjelder skripting nettlesere, og du vil ha rett for det meste. Den brukes også til servere. For eksempel brukes Node.js til å bygge raske, lette servere basert på V8 JavaScript-motor fra Google Chrome. JavaScript-motorer i nettlesere har tilgang til HTML-dokumentobjektmodellen (DOM) og kan manipulere HTML-elementer gjennom DOM. Gitt at forskjellige nettlesere har forskjellige DOM- og JavaScript-motorer, prøver rammer som jQuery å skjule implementeringsdetaljene fra programmereren.

Nashorn, og Rhino før den, støtter eksplisitt ikke nettleseren DOM. Implementert på JVM, blir de vanligvis kalt inn for sluttbrukerskripting i Java-applikasjoner. Nashorn og Rhino kan bygges inn i Java-programmer og brukes som kommandolinjeskall. Selvfølgelig er den ekstra magien som trengs når du skript Java fra JavaScript, å bygge bro over dataene og skrive uoverensstemmelser mellom de to språkene.

Problemer med neshorn

Neshornutvikling startet i Netscape i 1997 for et skjebnesvangert "Javagator" -prosjekt og ble gitt ut til Mozilla.org i 1998. Det ble da lisensiert til Sun og andre. Ærlig talt kan 1998 like godt være jura-perioden, som internettutviklingen går - 16 år senere har Rhino tydelig vist sin alder. I følge Jim Laskey fra Oracle, hovedutvikleren av Nashorn:

Jeg er sikker på at dette er sant, men som en trist utvikler og utviklingsansvarlig synes jeg siste setning er veldig morsom. Tross alt er store omskrivninger aldri morsomme. Å starte fra bunnen av er alltid morsomt.

Mål for Nashorn

Laskey beskrev sine mål for Nashorn slik:

  • Nashorn vil være basert på språkspesifikasjonen ECMAScript-262 Edition 5.1 og må bestå samsvarstestene for ECMAScript-262.
  • Nashorn vil støtte javax.script (JSR 223) API.
  • Støtte vil bli gitt for å påkalle Java-kode fra JavaScript og for Java å påkalle JavaScript-kode. Dette inkluderer direkte kartlegging til JavaBeans.
  • Nashorn vil definere et nytt kommandolinjeverktøy, jjs, for evaluering av JavaScript-kode i "shebang" -skript, her dokumenterer og redigerer strenger.
  • Ytelse og minnebruk av Nashorn-applikasjoner bør være betydelig bedre enn Rhino.
  • Nashorn vil ikke utsette noen ekstra sikkerhetsrisiko.
  • Medfølgende biblioteker skal fungere riktig under lokalisering.
  • Feilmeldinger og dokumentasjon vil bli internasjonalisert.

Laskey begrenset også eksplisitt omfanget av prosjektet med noen "ikke-mål":

  • Nashorn støtter bare ECMAScript-262 Edition 5.1. Den støtter ikke noen funksjoner i utgave 6 eller andre ikke-standardfunksjoner som leveres av andre JavaScript-implementeringer.
  • Nashorn inkluderer ikke et nettleser-plugin-programmeringsgrensesnitt.
  • Nashorn inkluderer ikke støtte for DOM / CSS eller relaterte biblioteker (for eksempel jQuery, Prototype eller Dojo).
  • Nashorn inkluderer ikke støtte for direkte feilsøking.

Så hva betyr det å være basert på ECMAScript-262 Edition 5.1? Differensiatoren her er at Rhino var basert på den eldre, mindre dyktige utgaven 3. The javax.script (JSR 223) API er for å ringe tilbake til JavaScript fra Java.

Mangelen på feilsøkingsstøtte i Nashorn er et skritt tilbake fra Rhino, som har sin egen JavaScript-feilsøking. Imidlertid finner du løsninger for denne bevisste utelatelsen i minst to populære IDEer.

Nashorn kommandolinjeverktøy: Installere jjs og jrunscript

Etter å ha lest om Nashorns kommandolinjeverktøy, jjs, Jeg var ivrig etter å prøve skallet på iMac, men etter installasjon av Java 8 var det ikke tilgjengelig for bash-skallet. Det viser seg at dokumentasjonen og implementeringen ikke var helt synkronisert.

Jeg visste at installasjonen hadde vært vellykket:

 > java -versjon java versjon "1.8.0" Java (TM) SE Runtime Environment (build 1.8.0-b132) Java HotSpot (TM) 64-Bit Server VM (build 25.0-b70, mixed mode) 

men løper jjs returnert -bash: jjs: kommandoen ble ikke funnet. Litt piking brakte meg til / usr / bin / katalog:

 > hvilken java / usr / bin / java 

Der fant jeg noe som heter jrunscript, som viste seg å være en variant av jjs som kjører et ekstra oppstartsskript. Det burde ha tilfredsstilt meg, men jeg var forvirret over hvorfor det ble dokumentert jjs verktøyet ble ikke installert i / usr / bin / med resten av Java 8 kjøretid. En liten undersøkelse fikk meg til å se på JavaVirtualMachines installasjon for Java 8. På en Mac, se etter jjs i /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/bin/ eller /Bibliotek/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/bin/.

Du kan definere et alias for jjs i sistnevnte katalog og legg den til i skallkonfigurasjonen hvis du trenger det for skripting på en Mac eller Linux. På en PC kan du legge til riktig jre / bin / katalog til din STI. I sin video fra lanseringen av Java 8 foreslår Jim Laskey å kopiere jjs til / usr / bin / katalog, men da jeg gjorde det, fant jeg det jjs kunne ikke finne JRE skikkelig ved kjøretid.

Kjører JavaScript-skript

Hvorfor de to kommandolinjeverktøyene for å kjøre JavaScript-skript? Jeg er ikke helt klar på hva utviklingsteamet tenkte, men jjs har evner som jrunscript ikke, og jrunscript har en initialiseringsfil. Nedenfor er noen enkle eksempler på jjs og jrunscript bruk.

 $ jrunscript nashorn> varsel ("hei,"); skriptfeil: ReferenceError: "alarm" er ikke definert i på linje nummer 1 

Dette fungerer ikke fordi varsling() er en nettleser / DOM-funksjon. D'oh! Jeg kunne ha sverget at det fungerte i Rhino, skjønt.

 nashorn> utskrift ("Hei,"); Hallo, 

Dette fungerer fordi print () er en kjerne JavaScript-funksjon.

 nashorn> var a = 1; nashorn> var b = "1"; nashorn> trykk (a + b); 11 nashorn> trykk (a + a); 2 nashorn> avslutte (); $ 

Med andre ord har vi et grunnleggende REPL-miljø (read-execute-print-loop-command-line) for JavaScript her. Hvis du er overrasket over svaret på a + b, vurder dette:

 nashorn> utskrift (typeof (a + b)); streng 

Det er en sjarmerende bivirkning av løs skriving og overbelastning av "+" -operatøren i JavaScript. Det er riktig oppførsel i henhold til JavaScript-spesifikasjonen, ikke en feil.

Nashorn støtter "#" -tegnet som en ledende kommentarmarkør, altså jjs og jrunscript kan brukes i kjørbare "shebang" -skripter skrevet i JavaScript. På en Mac eller Linux må du merke JavaScript-filen som kjørbar med chmod-verktøyet for å gjøre den kjørbar.

Du finner en skriptmodus i jjs at jrunscript ser ut til å mangle. I skriptemodus sendes uttrykk i bakflått til det ytre skallet for evaluering:

 $ jjs -scripting jjs> print ('ls'); Programmer Applikasjoner (Paralleller) Creative Cloud Files Desktop ... arbeid jjs>

Skriptmodus muliggjør også en utvidelse for "heredocs", som i utgangspunktet er flerlinjede strenger i et format som er kjent for Perl og Ruby-programmerere.

Forresten fungerer ikke piltastene på Mac-tastaturet ordentlig for linjeditering i jjs skall. Men det er et hack for det: Du kan brygge installer rlwrap og bruk det som en del av aliaset ditt for jjs i din .bashrc eller .zshrc fil.

Ringer JavaScript fra Java

For å ringe Nashorn JavaScript fra et Java 8-program, må du i utgangspunktet lage et nytt ScriptEngineManager forekomst og bruk det ScriptEngineManager for å laste Nashorn-skriptmotoren med navn. (Se dette Stack Overflow-spørsmålet for et lite sammendrag av lasting og feilsøking av Nashorn.)

Til slutt kan du sende Nashorn-motoren en fil eller en streng for å evaluere:

 importere javax.script.Invocable; importere javax.script.ScriptEngine; importere javax.script.ScriptEngineManager; importere javax.script.ScriptException; ... prøv {ScriptEngineManager fabrikk = ny ScriptEngineManager (); ScriptEngine engine = factory.getEngineByName ("nashorn"); engine.eval ("load (\" "+" src "+" / "+" javascript_sample "+" / "+" test1.js "+" \ ");"); } fange (Unntak ex) {// ...} ... prøv {ScriptEngineManager fabrikk = ny ScriptEngineManager (); ScriptEngine engine = factory.getEngineByName ("nashorn"); engine.eval ("function hi () {\ nvar a = 'PROSPER'.toLowerCase (); \ nmiddle (); \ nprint (' Live long and '+ a)} \ n function middle () {\ n var b = 1; for (var i = 0, max = 5; i

Merk at skript alltid kan genereres ScriptException feil, så du må fange dem.

Ringer til Java fra JavaScript

Å ringe Java fra Nashorn er omtrent så enkelt som det kan være, siden Java 8-klassebibliotekene er innebygd i Nashorn:

 skriv ut (java.lang.System.currentTimeMillis ()); var file = new java.io.File ("sample.js"); skriv ut (file.getAbsolutePath ()); skrive ut (file.absolutePath); 

Merk at Nashorn ikke importerer java pakke som standard, fordi referanser til String eller Gjenstand konflikt med de tilsvarende typene i JavaScript. Derfor er en Java-streng java.lang.Streng, ikke String.

Nashorn og JavaFX

Hvis du påberoper deg jjs med -fx bytte, vil det tillate deg å bruke visuelle JavaFX-klasser i Nashorn-applikasjonene dine. For eksempel viser følgende eksempel fra Oracle-dokumentasjonen en JavaFX-knapp:

 var Button = javafx.scene.control.Button; var StackPane = javafx.scene.layout.StackPane; var Scene = javafx.scene.Scene; funksjonsstart (primaryStage) {primaryStage.title = "Hei verden!"; var-knapp = ny knapp (); button.text = "Si 'Hello World'"; button.onAction = function () print ("Hello World!"); var root = ny StackPane (); root.children.add (knapp); primaryStage.scene = ny scene (root, 300, 250); primaryStage.show (); } 

Feilsøking Nashorn

Jeg nevnte tidligere at Nashorn ikke inkluderer en egen feilsøking. Heldigvis støtter både NetBeans 8 og IntelliJ IDEA 13.1 feilsøking av Nashorn JavaScript. Stack Overflow-spørsmålet jeg nevnte tidligere inkluderer et nyttig NetBeans 8-prosjekt som du kan bruke som et eksempel. Du vil oppdage at ved å bruke feilsøkingselementet fra lokalmenyen på JavaScript-filer, kan du feilsøke Nashorn-koden.

I IntelliJ IDEA 13 kan du angi brytepunkter i Java- og Nashorn JavaScript-filene ved hjelp av samme hurtigtast (Com / Ctrl-F8). Når du treffer et JavaScript-brytpunkt, får du all vanlig feilsøkingsinformasjon.

Nashorn ble designet for å være en bedre, raskere erstatning for den gamle Rhino-motoren, og etter de fleste mål lykkes den. Det har noen mindre vorter som jeg håper vil bli rettet i fremtidige oppdateringer, men foreløpig er det rimelige hacks som lar deg bruke Nashorn effektivt i prosjektene dine.

$config[zx-auto] not found$config[zx-overlay] not found