JavaOne 2012 CON3978 Scripting Languages on the JVM

42

Click here to load reader

description

An introduction to embedding your scripting language on the JVM

Transcript of JavaOne 2012 CON3978 Scripting Languages on the JVM

Page 1: JavaOne 2012 CON3978 Scripting Languages on the JVM

© 2012 IBM Corporation

How to embed your scripting languageJavaOne 2012 - CON3978

Paul Thwaite – Java 8 Quality Assurance EngineerMonday 1 October 2012

Page 2: JavaOne 2012 CON3978 Scripting Languages on the JVM

2 © 2012 IBM Corporation

Important Disclaimers

THE INFORMATION CONTAINED IN THIS PRESENTATION IS PROVIDED FOR INFORMATIONAL PURPOSES ONLY.

WHILST EFFORTS WERE MADE TO VERIFY THE COMPLETENESS AND ACCURACY OF THE INFORMATION CONTAINED IN THIS PRESENTATION, IT IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.

ALL PERFORMANCE DATA INCLUDED IN THIS PRESENTATION HAVE BEEN GATHERED IN A CONTROLLED ENVIRONMENT. YOUR OWN TEST RESULTS MAY VARY BASED ON HARDWARE, SOFTWARE OR INFRASTRUCTURE DIFFERENCES.

ALL DATA INCLUDED IN THIS PRESENTATION ARE MEANT TO BE USED ONLY AS A GUIDE.

IN ADDITION, THE INFORMATION CONTAINED IN THIS PRESENTATION IS BASED ON IBM’S CURRENT PRODUCT PLANS AND STRATEGY, WHICH ARE SUBJECT TO CHANGE BY IBM, WITHOUT NOTICE.

IBM AND ITS AFFILIATED COMPANIES SHALL NOT BE RESPONSIBLE FOR ANY DAMAGES ARISING OUT OF THE USE OF, OR OTHERWISE RELATED TO, THIS PRESENTATION OR ANY OTHER DOCUMENTATION.

NOTHING CONTAINED IN THIS PRESENTATION IS INTENDED TO, OR SHALL HAVE THE EFFECT OF:

- CREATING ANY WARRANT OR REPRESENTATION FROM IBM, ITS AFFILIATED COMPANIES OR ITS OR THEIR SUPPLIERS AND/OR LICENSORS

Page 3: JavaOne 2012 CON3978 Scripting Languages on the JVM

3 © 2012 IBM Corporation

Introduction to the speaker – Paul Thwaite

■ 11 years experience developing and deploying Java SDKs

■ Recent work focus:– Quality Assurance specialist

• Leading cross-continent teams• System Test on IBM SDKs

– Quality assurance lead for Java 8• Focus on testing in OpenJDK• OpenJDK contributor

■ My contact information:– [email protected]– linkedin.com/profile/view?id=26327969

Page 4: JavaOne 2012 CON3978 Scripting Languages on the JVM

4 © 2012 IBM Corporation

What you will learn from this talk

■ Why me and what I do■ Why we run scripting languages on the JVM■ Methods of embedding■ Models of embedding ■ Comparison of two embedding frameworks■ Which approach is best

Page 5: JavaOne 2012 CON3978 Scripting Languages on the JVM

5 © 2012 IBM Corporation

Why me and what I do

■ Test IBM's Java SDK– I break Java

■ Focus on system testing in QA– Multi-threaded load testing– Third-party applications

■ Increasing use of scripting languages running on the JVM– We need to ensure they run on the IBM SDK

Page 6: JavaOne 2012 CON3978 Scripting Languages on the JVM

6 © 2012 IBM Corporation

How many languagesrun on the JVM?

Page 7: JavaOne 2012 CON3978 Scripting Languages on the JVM

7 © 2012 IBM Corporation

How many languagesrun on the JVM?

>800total

http://en.wikipedia.org/wiki/List_of_JVM_languages

>60active

Page 8: JavaOne 2012 CON3978 Scripting Languages on the JVM

8 © 2012 IBM Corporation

How many languagesrun on the JVM?

Most popular include

Page 9: JavaOne 2012 CON3978 Scripting Languages on the JVM

9 © 2012 IBM Corporation

How many languagesrun on the JVM?

Most popular include

JavaScript

Page 10: JavaOne 2012 CON3978 Scripting Languages on the JVM

10 © 2012 IBM Corporation

How many languagesrun on the JVM?

Why is the JVM so popular?

Page 11: JavaOne 2012 CON3978 Scripting Languages on the JVM

11 © 2012 IBM Corporation

Why is the JVM so popular?

■ Runtime performance benefits■ Threading and scaling support■ JVM profiling tools■ Access to the impressive array of Java APIs■ Support for multiple languages

The JVM is fast

Page 12: JavaOne 2012 CON3978 Scripting Languages on the JVM

12 © 2012 IBM Corporation

How many languagesrun on the JVM?

Let's examine a few implementation methods

Page 13: JavaOne 2012 CON3978 Scripting Languages on the JVM

13 © 2012 IBM Corporation

Implementation Methods

■ Compiled to bytecodes– Jython– Groovy– Scala

Page 14: JavaOne 2012 CON3978 Scripting Languages on the JVM

14 © 2012 IBM Corporation

Implementation Methods

■ Compiled to bytecodes– Jython– Groovy– Scala

■ Interpreted on the JVM– JavaScript– JRuby

Page 15: JavaOne 2012 CON3978 Scripting Languages on the JVM

15 © 2012 IBM Corporation

Implementation Methods

■ Compiled to bytecodes– Jython– Groovy– Scala

■ Interpreted on the JVM– JavaScript– JRuby

■ Embedded in a Java application on the JVM– Jython– Groovy– Scala– JavaScript– JRuby

Page 16: JavaOne 2012 CON3978 Scripting Languages on the JVM

16 © 2012 IBM Corporation

Compiled to bytecodes

MyJythonApp

JythoncCompiler

JVM

MyJythonApp.classMyJythonApp.py

Compiling a Jython script to bytecodes and running it on the JVM

Page 17: JavaOne 2012 CON3978 Scripting Languages on the JVM

17 © 2012 IBM Corporation

Interpreted on the JVM

JRuby.rbJRuby JavaInterpreter

JVM

Interpreting a JRuby script on the JVM

The JRuby language provides the interpreter in Java

Page 18: JavaOne 2012 CON3978 Scripting Languages on the JVM

18 © 2012 IBM Corporation

Embedding in a Java application

Ruby.rb

Embedding and running a JRuby script inside a Java application on the JVM

MyJavaApp.class JRubyEmbed Engine

JVM

The language provides the embed engine

Page 19: JavaOne 2012 CON3978 Scripting Languages on the JVM

19 © 2012 IBM Corporation

Embedding in a Java application – multiple scripts

Embedding and running multiple scripts inside a Java application on the JVM

The language provides the embed engine

Ruby.rb

Ruby.rb

JRuby.rb

JavaScript.js

MyJavaApp.class

JRubyEmbed Engine

JVM

JavascriptEmbed Engine

JRubyEmbed Engine

JavaScriptEmbed Engine

Page 20: JavaOne 2012 CON3978 Scripting Languages on the JVM

20 © 2012 IBM Corporation

Scripting on the JVM

Models

Page 21: JavaOne 2012 CON3978 Scripting Languages on the JVM

21 © 2012 IBM Corporation

Scripting on the JVM - Models

Script Java

JVM

Java Script

JVM

Java Script

JVM

Page 22: JavaOne 2012 CON3978 Scripting Languages on the JVM

22 © 2012 IBM Corporation

Scripting on the JVM – Script domain knowledge

■ Java objects are created and used from inside the script

■ Requires– Scripting language

knowledge to implement Java objects

– Java knowledge

■ Limited re-use capabilities– Not portable code– Locked in to using the

chosen scripting language

Language-specifc

Script Java

JVM

require 'java'frame = javax.swing.JFrame.new("Window") label = javax.swing.JLabel.new("Hello")frame.getContentPane.add(label)frame.setDefaultCloseOperation (javax.swing.JFrame::EXIT_ON_CLOSE)frame.packframe.setVisible(true)

Page 23: JavaOne 2012 CON3978 Scripting Languages on the JVM

23 © 2012 IBM Corporation

Scripting on the JVM – Java domain knowledge

■ Java runs a script which is embedded within the Java application

■ The APIs used to invoke the script belong to the scripting language

■ Requires– Java knowledge– Language embed API

knowledge– Bridging knowledge

■ Re-use existing scripts– Optional bridge for

legacy scripts– Investment in using

chosen scripting language

Java Script

JVM

Bridge

import org.jruby.embed.*;ScriptingContainer container = new ScriptingContainer();container.runScriptlet(PathType.RELATIVE, "myscripts/ruby.rb");

Page 24: JavaOne 2012 CON3978 Scripting Languages on the JVM

24 © 2012 IBM Corporation

Scripting on the JVM – Java and script domain knowledge

■ Options– Invoke a script from a

Java application– Create and use Java

objects inside a script

■ Requires– Java knowledge– Knowledge of the JSR

223 API– Some knowledge of the

scripting language may be required

■ Re-use existing scripts– Support for multiple

scripts

Java Script

JVM

import javax.script.*;ScriptEngineManager engineMgr = new ScriptEngineManager();ScriptEngine engine = engineMgr.getEngineByName("jruby");InputStream is = this.getClass().getResourceAsStream("/myscripts/ruby.rb");Reader reader = new InputStreamReader(is);engine.eval(reader);

Page 25: JavaOne 2012 CON3978 Scripting Languages on the JVM

25 © 2012 IBM Corporation

What is embedding?

Page 26: JavaOne 2012 CON3978 Scripting Languages on the JVM

26 © 2012 IBM Corporation

Embedding in a Java application – multiple scripts

Embedding and running multiple scripts inside a Java application on the JVM

The language provides the embed engine

Ruby.rb

Ruby.rb

Ruby.rb

JavaScript.js

MyJavaApp.class

JRubyEmbed Engine

JVM

JavascriptEmbed Engine

JRubyEmbed Engine

JavaScriptEmbed Engine

Page 27: JavaOne 2012 CON3978 Scripting Languages on the JVM

27 © 2012 IBM Corporation

What can you do with an embedded language?

Embedding

Run a script

Call a script's function andretrieve its return valueConfigure script

environment

Pass variables to the script

Run multiple scripts on the

same JVM

Retrieve variables from

the script

Page 28: JavaOne 2012 CON3978 Scripting Languages on the JVM

28 © 2012 IBM Corporation

Ways to embed a scripting language on the JVM

JSR 223

javax.script

Implementations

Language-specific

Embed

Implementations

● A common API for embedding multiple languages

● Implementation provided by the language

● Some popular languages provide a javax.script API

● Implementation provided by the language

● Similar to JSR223● Extensions available● Ability to fine-tune the scripting

environment● Most popular languages provide

an embed API

Page 29: JavaOne 2012 CON3978 Scripting Languages on the JVM

29 © 2012 IBM Corporation

Comparison of embedding frameworks

JSR 223

javax.script

Implementations

Language-specific

Embed

Implementationsvs

■ Introduction to javax.script■ Code examples using these languages

– Jruby– Jython– Groovy

■ Exception handling may be missed off some examples to save space

Page 30: JavaOne 2012 CON3978 Scripting Languages on the JVM

30 © 2012 IBM Corporation

What is javax.script?

■ Allows a developer to embed a scripting language in a Java application ■ Available from Java 6 SE■ Implementation provided by the scripting language■ JSR 223 specification defines 6 interfaces

– ScriptEngine– ScriptEngineFactory– ScriptContext– Bindings– Invocable– Compilable

■ Setup– Download the JSR 223 implementation from your language provider's website– Add the jar(s) to the CLASSPATH– Add your script directory to the CLASSPATH

■ ScriptEngine is discovered at runtime via the JAR services mechanism

JSR 223 Scripting for the Java Platform

Page 31: JavaOne 2012 CON3978 Scripting Languages on the JVM

31 © 2012 IBM Corporation

Example: Query JAR services for installed JSR223 Java Scripting Engines

import javax.script.*;public class ListScriptEngines {

public static void main(String[] args) {ScriptEngineManager mgr = new ScriptEngineManager();List<ScriptEngineFactory> factories = mgr.getEngineFactories();for (ScriptEngineFactory factory: factories) {

String engName = factory.getEngineName(); String engVersion = factory.getEngineVersion(); System.out.println("Script Engine: " + engName + " V" + engVersion);

} }

}

Output to stdout:Script Engine: Groovy Scripting Engine V2.0Script Engine: jython V2.5.3Script Engine: JSR 223 JRuby Engine V1.6.7.2Script Engine: Mozilla Rhino V1.7 release 3 PRERELEASE

JSR 223

Page 32: JavaOne 2012 CON3978 Scripting Languages on the JVM

32 © 2012 IBM Corporation

Example: Embedding a Ruby script into a Java application

import javax.script.*;ScriptEngineManager engineMgr = new ScriptEngineManager();ScriptEngine engine = engineMgr.getEngineByName("jruby");InputStream is = this.getClass().getResourceAsStream("/myscripts/ruby.rb");Reader reader = new InputStreamReader(is);engine.eval(reader); //throws ScriptException

Script: /myscripts/ruby.rbstringHello = "Hello, I am a jruby script!"puts "#{stringHello.to_s}"

Output to stdout:Hello, I am a ruby script!"

JSR 223 - JRuby

import org.jruby.embed.*;ScriptingContainer container = new ScriptingContainer();container.runScriptlet(PathType.RELATIVE, "myscripts/ruby.rb");

JRuby Embed API

Page 33: JavaOne 2012 CON3978 Scripting Languages on the JVM

33 © 2012 IBM Corporation

Example: Passing a variable to a Jython script and retrieving it back again

import javax.script.*;ScriptEngineManager engineMgr = new ScriptEngineManager();ScriptEngine engine = engineMgr.getEngineByName("jython");InputStream is = this.getClass().getResourceAsStream("/myscripts/jython_var.py");Reader reader = new InputStreamReader(is);try {

engine.put("javaString", "red green blue");engine.eval(reader);System.out.println("java> received " + engine.get("javaString"));

} catch (ScriptException e) {}

Script: /myscripts/jython_var.pyprint "jython> received " + javaString javaString += " yellow indigo white"

Output to stdout:jython> received red green bluejava> received red green blue yellow indigo white

JSR 223 - Jython

import org.python.util.PythonInterpreter;PythonInterpreter python = new PythonInterpreter();python.set ( "javaString", new org.python.core.PyString("red green blue"));python.execfile ( "myscripts/jython_var.py" );System.out.println("java> received " + python.get ("javaString"));

Jython Embed API

Page 34: JavaOne 2012 CON3978 Scripting Languages on the JVM

34 © 2012 IBM Corporation

Example: Invoke a Groovy function with a return value

ScriptEngineManager engineMgr = new ScriptEngineManager();ScriptEngine engine = engineMgr.getEngineByName("groovy");InputStream is = this.getClass().getResourceAsStream("/myscripts/groovy_func.groovy");Reader reader = new InputStreamReader(is);if (engine instanceof Invocable) { //Invocable is an optional interface

Invocable invocableEngine = (Invocable) engine;engine.eval(reader);System.out.println("java> What's the Square root of 360?");double squareRoot = (double) invocableEngine.invokeFunction("squareRoot", 360);System.out.println("java> " + squareRoot);

}

Script: /myscripts/groovy_func.groovydef squareRoot(number) { println "groovy> Sqrt of ${number} is" Math.sqrt(number)}

Output to stdout:java> What's the square root of 360?groovy> Sqrt of 360 isjava> 18.973665961010276

JSR 223 - Groovy

String[] roots = new String[] { "C:\\scripts" };GroovyScriptEngine gse = new GroovyScriptEngine(roots);Class<?> groovyClass = gse.loadScriptByName("groovy_func.groovy");GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance();System.out.println("java> What's the square root of 360?");System.out.println("java> " + groovyObject.invokeMethod("squareRoot", 360).toString());

Groovy Embed API

Page 35: JavaOne 2012 CON3978 Scripting Languages on the JVM

35 © 2012 IBM Corporation

Example: How to set options in JRuby

// Make JRuby's engine thread safeSystem.setProperty("org.jruby.embed.localcontext.scope", “threadsafe”);

// Turn on JIT verbose loggingSystem.setProperty("jruby.jit.logging.verbose", “true”);

// Set JRuby homeSystem.setProperty("jruby.home", “/path/to/jruby”);

■ JRuby provides many options to the developer to allow for the JRuby ScriptEngine to be customised and finely-tuned

■ In JRuby, these options are set using SystemProperty– Outside the spec of JSR 223– Requires language-specific knowledge

Page 36: JavaOne 2012 CON3978 Scripting Languages on the JVM

36 © 2012 IBM Corporation

Example: Comparison of setting options in JRuby

■ Jruby's EmbedCore API– Set on a per engine basis– Well documented and easy to find

■ Javax.script API– Set system wide– Multiple engines will all have the same behaviour– Harder to find documentation (not part of an API)

// JRuby EmbedCore API// Make JRuby's engine thread safe// Set via a constructor argument of ScriptingcontainerScriptingContainer instance = new ScriptingContainer(LocalContextScope.THREADSAFE);

// JSR 223 API// Make JRuby's engine thread safeSystem.setProperty("org.jruby.embed.localcontext.scope", “threadsafe”);

Page 37: JavaOne 2012 CON3978 Scripting Languages on the JVM

37 © 2012 IBM Corporation

Example: Comparison of setting options in Groovy

// Groovy Embed API// Set the compiler warning message levelCompilerConfiguration.setWarningLevel(int warningLevel);

// JSR 223 API// Set the compiler warning message levelNo easy way to do it

Page 38: JavaOne 2012 CON3978 Scripting Languages on the JVM

38 © 2012 IBM Corporation

How far does javax.script go?

■ Provides useful interaction between Java and many scripting languages– Plug 'n Play support for multiple languages– Great for simple embedding– Easy-to-use API

■ Limitations– The Invocable and Compilable interfaces are optional– Setting language-specific options removes the abstraction JSR 223 provides– Not all engines will provide the same configuration options– Requires knowledge of the underlying ScriptEngine implementation beyond JSR 223

Page 39: JavaOne 2012 CON3978 Scripting Languages on the JVM

39 © 2012 IBM Corporation

Scripting on the JVM is great

■ Some of the most popular languages support Java embedding■ Embedding a language in a new application is easy to get started■ Deciding how to embed has consequences

–JSR 223 is a great framework for basic embedding

–If you need to harness the power of the language, you will need to use the language API

• For example, JRuby Embed Core

■ How are you embedding your scripting language on the JVM?

Page 40: JavaOne 2012 CON3978 Scripting Languages on the JVM

40 © 2012 IBM Corporation

References

■ JSR 223– JSR 223 specification

• http://www.jcp.org/en/jsr/detail?id=223

– JRuby implementation• http://kenai.com/projects/jruby/pages/JavaIntegration

– Groovy implementation• http://groovy.codehaus.org/JSR+223+Scripting+with+Groovy

■ Jython Java Integration– http://www.jython.org/jythonbook/en/1.0/JythonAndJavaIntegration.html

■ Scripting in Java: Languages, Frameworks, and Patterns– Dejan Bosanac, Addison-Wesley

Page 41: JavaOne 2012 CON3978 Scripting Languages on the JVM

41 © 2012 IBM Corporation

References

■ Get Products and Technologies:– IBM Java Runtimes and SDKs:

• https://www.ibm.com/developerworks/java/jdk/– IBM Monitoring and Diagnostic Tools for Java:

• https://www.ibm.com/developerworks/java/jdk/tools/

■ Learn:– IBM Java InfoCenter:

• http://publib.boulder.ibm.com/infocenter/java7sdk/v7r0/index.jsp

■ Discuss:– IBM Java Runtimes and SDKs Forum:

• http://www.ibm.com/developerworks/forums/forum.jspa?forumID=367&start=0

Page 42: JavaOne 2012 CON3978 Scripting Languages on the JVM

42 © 2012 IBM Corporation

Copyright and Trademarks

© IBM Corporation 2011. All Rights Reserved.

IBM, the IBM logo, and ibm.com are trademarks or registered trademarks of International Business Machines Corp., and registered in many jurisdictions worldwide.

Other product and service names might be trademarks of IBM or other companies.

A current list of IBM trademarks is available on the Web – see the IBM “Copyright and trademark information” page at URL: www.ibm.com/legal/copytrade.shtml