Your SlideShare is downloading. ×
0
Scala for Scripting
Implementing an OSGi enabled, JSR-223 compliant scripting engine for Scala
http://people.apache.org/~m...
Agenda
■ Introduction
  – Scripting with Scala
  – Scala for Apache Sling
■ Requirements and goals
■ Challenges and soluti...
Scripting with Scala
■ (Illusion of) executing source code
■ Concise and versatile*
     var capitals = Map("Switzerland" ...
Scripting with Scala (cont.)
■ XML literals: type safe templating
  <html>
    <head>
      <link rel="stylesheet" href="/...
Apache Sling
■ Web application framework
  – Backed by a Java content repository (JSR-170/JSR-283):
    Apache Jackrabbit
...
Sling URL decomposition

  GET   /forum/scala4sling.html   HTTP/1.1




                                             X
Sling URL decomposition

  GET   /forum/scala4sling.html   HTTP/1.1




                                             X
Sling URL decomposition

    GET    /forum/scala4sling.html   HTTP/1.1

Repository path




                              ...
Sling URL decomposition

    GET    /forum/scala4sling.html   HTTP/1.1

Repository path




                  Application
...
Sling URL decomposition

    GET    /forum/scala4sling.html     HTTP/1.1

Repository path                      Script sele...
Scala for Sling
package forum


class html(args: htmlArgs) {
  import args._
    // further imports omitted


    println ...
Scala for Sling
package forum


class html(args: htmlArgs) {
  import args._                                       Import ...
Scala for Sling
package forum


class html(args: htmlArgs) {
  import args._                                       Import ...
Agenda
■ Introduction
■ Requirements and goals
  – JSR-223 compliance
  – OSGi tolerant
  – Further design goals
■ Challen...
JSR-223
■ Scripting for the Java language
  – Allow scripts access to the Java Platform
  – Scripting for Java server-side...
JSR-223: usage
val factories = ServiceRegistry.lookupProviders(classOf[ScriptEngineFactory])
val factory = factories.find(...
OSGi
■ OSGi Service Platform
  – Runtime environment for Java applications (bundles)
  – Module system
  – Life cycle mana...
Further design goals
■ Leverage existing tools
  – Compilers
  – IDEs
  – Test suites
  – Documentation and reporting tool...
Agenda
■ Introduction
■ Requirements and goals
■ Challenges and solutions
  – Leverage existing tools
  – Passing argument...
Leverage existing tools
■ Scripts are valid Scala source entities
■ Tradeoff
  – ceremony
    package forum


    class ht...
Unit testing
class html(args: htmlArgs) {
    import args._
    // further imports omitted


    println {
      <html>
  ...
Unit testing
class html(args: htmlArgs) {
    import args._                                     class htmlArgs {
    // fu...
Unit testing
class html(args: htmlArgs) {
    import args._                                     class htmlArgs {
    // fu...
Passing arguments to Scripts
class ResettableOutStream extends OutputStream implements Resettable {
  public void write(in...
Passing arguments to Scripts
class ResettableOutStream extends OutputStream implements Resettable {
  public void write(in...
Passing arguments to Scripts
class ResettableOutStream extends OutputStream implements Resettable {
  public void write(in...
Bindings wrapper
■ No type information in javax.script.Bindings
  – Generate bindings wrapper exposing static types
  – Ar...
Bindings wrapper (cont.)
class ResettableOutStream extends OutputStream implements Resettable {
  public void write(int b)...
Bindings wrapper (cont.)
class ResettableOutStream extends OutputStream implements Resettable {
  public void write(int b)...
Bindings wrapper (cont.)
class ResettableOutStream extends OutputStream implements Resettable {
  public void write(int b)...
Bindings wrapper (cont.)
■ Limitations
  – Scala’s visibility modifiers not exposed through reflection
  – Not yet working...
Scalac and OSGi
■ Scalac
  – Requires compiler class path
  – File system based
■ OSGi
  – Provides class loaders
  – Bund...
Independent through configuration
■ Abstract implementation details into configuration class
  – Default implementation fo...
Configuration
■ Scala compiler
  – Per script engine
  – scripting.scala.SettingsProvider
  – Class and output paths: scal...
Performance
■ On the fly compilation is slow
  – Cache pre compiled scripts
  – Dependency on bindings: include bindings w...
Conclusion
■ Scala is attractive for scripting
  – Concise and versatile
  – DSL capabilities
  – Type safe
  – XML litera...
References
■ Scala for Scripting
  http://people.apache.org/~mduerig/scala4scripting/
■ Apache Sling
  http://sling.apache...
Upcoming SlideShare
Loading in...5
×

Scala for scripting

2,171

Published on

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,171
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
15
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Transcript of "Scala for scripting"

  1. 1. Scala for Scripting Implementing an OSGi enabled, JSR-223 compliant scripting engine for Scala http://people.apache.org/~mduerig/scala4scripting/ Michael Dürig michael.duerig@day.com Day Software AG http://www.day.com/ Scala Days 2010 April 15th 1
  2. 2. Agenda ■ Introduction – Scripting with Scala – Scala for Apache Sling ■ Requirements and goals ■ Challenges and solutions ■ Conclusion 2
  3. 3. Scripting with Scala ■ (Illusion of) executing source code ■ Concise and versatile* var capitals = Map("Switzerland" -> "Bern", "Spain" -> "Madrid") capitals += ("France" -> "Paris") val c = capitals.find(_._1 == "France") .map(_._2) .getOrElse("NIL") ■ DSL capabilities ■ Type safe *) Adapted from: Programming in Scala, Martin Odersky, Lex Spoon, Bill Venners. Artima, 2008. 3
  4. 4. Scripting with Scala (cont.) ■ XML literals: type safe templating <html> <head> <link rel="stylesheet" href="/apps/forum/static/blue.css" /> </head> <body> <div id="Header"> Welcome to the { node("name") } forum { Calendar.getInstance.getTime } </div> <div id="Content"> { SearchBox.render(request) } { ThreadOverview.render(node) } </div> </body> </html> 4
  5. 5. Apache Sling ■ Web application framework – Backed by a Java content repository (JSR-170/JSR-283): Apache Jackrabbit – Based on OSGi: Apache Felix – http://sling.apache.org/ ■ RESTful – Content resolution for mapping request URLs to resources (i.e. JCR nodes) – Servlet resolution for mapping resources to request handlers (i.e. scripts) ■ Scriptable application layer – JSR-223: Scripting for the Java platform 5
  6. 6. Sling URL decomposition GET /forum/scala4sling.html HTTP/1.1 X
  7. 7. Sling URL decomposition GET /forum/scala4sling.html HTTP/1.1 X
  8. 8. Sling URL decomposition GET /forum/scala4sling.html HTTP/1.1 Repository path X
  9. 9. Sling URL decomposition GET /forum/scala4sling.html HTTP/1.1 Repository path Application selection X
  10. 10. Sling URL decomposition GET /forum/scala4sling.html HTTP/1.1 Repository path Script selection Application selection X
  11. 11. Scala for Sling package forum class html(args: htmlArgs) { import args._ // further imports omitted println { <html> <body> <div id="Header"> Welcome to the { node("name") } forum { Calendar.getInstance.getTime } </div> <div id="Content"> { SearchBox.render(request) } { ThreadOverview.render(node) } </div> </body> </html> } } 6
  12. 12. Scala for Sling package forum class html(args: htmlArgs) { import args._ Import bindings // further imports omitted println { <html> <body> <div id="Header"> Welcome to the { node("name") } forum { Calendar.getInstance.getTime } </div> <div id="Content"> { SearchBox.render(request) } { ThreadOverview.render(node) } </div> </body> </html> } } 6
  13. 13. Scala for Sling package forum class html(args: htmlArgs) { import args._ Import bindings // further imports omitted println { <html> <body> <div id="Header"> Welcome to the { node("name") } forum { Calendar.getInstance.getTime } </div> Use arguments <div id="Content"> { SearchBox.render(request) } { ThreadOverview.render(node) } </div> </body> </html> } } 6
  14. 14. Agenda ■ Introduction ■ Requirements and goals – JSR-223 compliance – OSGi tolerant – Further design goals ■ Challenges and solutions ■ Conclusion 7
  15. 15. JSR-223 ■ Scripting for the Java language – Allow scripts access to the Java Platform – Scripting for Java server-side applications – Executing scripts: javax.script.{ScriptEngine, ScriptEngineFactory} – Binding application objects into scripts: javax.script.Bindings 8
  16. 16. JSR-223: usage val factories = ServiceRegistry.lookupProviders(classOf[ScriptEngineFactory]) val factory = factories.find(_.getEngineName == "Scala Scripting Engine") val engine = factory.map(_.getScriptEngine).getOrElse { throw new Error("Cannot locate Scala scripting engine") } val bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE) bindings.put("request", servletRequest) engine.eval(script, bindings) 9
  17. 17. OSGi ■ OSGi Service Platform – Runtime environment for Java applications (bundles) – Module system – Life cycle management – Service registry ■ Mostly transparent – Bundle information in manifest file – Relies on class loading 10
  18. 18. Further design goals ■ Leverage existing tools – Compilers – IDEs – Test suites – Documentation and reporting tools ■ Independent from Sling and OSGi – Versatile – Configurable – Embeddable 11
  19. 19. Agenda ■ Introduction ■ Requirements and goals ■ Challenges and solutions – Leverage existing tools – Passing arguments to scripts – Scalac and OSGi – Performance ■ Conclusion 12
  20. 20. Leverage existing tools ■ Scripts are valid Scala source entities ■ Tradeoff – ceremony package forum class html(args: htmlArgs) { import args._ // ... } ■ Advantages – Write, refactor and debug with Scala IDEs – Compile with Scala compiler – Unit testing 13
  21. 21. Unit testing class html(args: htmlArgs) { import args._ // further imports omitted println { <html> <body> <div id="Header"> Welcome to the { node("name") } forum { Calendar.getInstance.getTime } </div> <div id="Content"> { SearchBox.render(request) } { ThreadOverview.render(node) } </div> </body> </html> } } 14
  22. 22. Unit testing class html(args: htmlArgs) { import args._ class htmlArgs { // further imports omitted val node = new { println { def apply(name: String) = "Scala scripting" <html> <body> } <div id="Header"> val request = new { /* ... */ } Welcome to the { node("name") } forum { Calendar.getInstance.getTime } } </div> <div id="Content"> { SearchBox.render(request) } new html(new htmlArgs) { ThreadOverview.render(node) } </div> </body> </html> } } 14
  23. 23. Unit testing class html(args: htmlArgs) { import args._ class htmlArgs { // further imports omitted val node = new { println { def apply(name: String) = "Scala scripting" <html> <body> } <div id="Header"> val request = new { /* ... */ } Welcome to the { node("name") } forum { Calendar.getInstance.getTime } } </div> <div id="Content"> { SearchBox.render(request) } new html(new htmlArgs) { ThreadOverview.render(node) } </div> </body> </html> } <html> } <body> <div id="Header"> Welcome to the Scala scripting forum Tue Mar 16 19:46:38 CET 2010 </div> <div id="Content"> <!-- output omitted --> </div> </body> </html> 14
  24. 24. Passing arguments to Scripts class ResettableOutStream extends OutputStream implements Resettable { public void write(int b) throws IOException { /* ... */ } public void reset() { /* ... */ } } OutputStream getResetableOutputStream() { /* ... */ } bindings.put("output", getResetableOutputStream) engine.eval(script, bindings) class html(args: htmlArgs) { import args._ output.write(‘c’) output.reset() } 15
  25. 25. Passing arguments to Scripts class ResettableOutStream extends OutputStream implements Resettable { public void write(int b) throws IOException { /* ... */ } public void reset() { /* ... */ } } OutputStream getResetableOutputStream() { /* ... */ } bindings.put("output", getResetableOutputStream) engine.eval(script, bindings) Where are the types? class html(args: htmlArgs) { import args._ output.write(‘c’) output.reset() } 15
  26. 26. Passing arguments to Scripts class ResettableOutStream extends OutputStream implements Resettable { public void write(int b) throws IOException { /* ... */ } public void reset() { /* ... */ } } OutputStream getResetableOutputStream() { /* ... */ } bindings.put("output", getResetableOutputStream) engine.eval(script, bindings) Where are the types? class html(args: htmlArgs) { import args._ Bindings wrapper output.write(‘c’) provides static types output.reset() } 15
  27. 27. Bindings wrapper ■ No type information in javax.script.Bindings – Generate bindings wrapper exposing static types – Arguments appear to be of all accessible types – Implicit conversions to the rescue ■ Least accessible types – v: C, I1, ..., In – Expose v with static type D of least accessible super type of C – Expose v through implicit conversion to Ik if neither D nor any Im (m ≠ k) implements Ik. 16
  28. 28. Bindings wrapper (cont.) class ResettableOutStream extends OutputStream implements Resettable { public void write(int b) throws IOException { /* ... */ } public void reset() { /* ... */ } } OutputStream getResetableOutputStream() { /* ... */ } bindings.put("output", new ResettableOutStream) engine.eval(script, bindings) 17
  29. 29. Bindings wrapper (cont.) class ResettableOutStream extends OutputStream implements Resettable { public void write(int b) throws IOException { /* ... */ } public void reset() { /* ... */ } } OutputStream getResetableOutputStream() { /* ... */ } bindings.put("output", new ResettableOutStream) engine.eval(script, bindings) Bindings wrapper class htmlArgs(bindings: Bindings) { lazy val output = bindings.getValue("output").asInstanceOf[OutputStream] implicit def outputStream2Resettable(x: OutputStream): Resettable = x.asInstanceOf[Resettable] } 17
  30. 30. Bindings wrapper (cont.) class ResettableOutStream extends OutputStream implements Resettable { public void write(int b) throws IOException { /* ... */ } public void reset() { /* ... */ } } OutputStream getResetableOutputStream() { /* ... */ } bindings.put("output", new ResettableOutStream) engine.eval(script, bindings) Bindings wrapper class htmlArgs(bindings: Bindings) { lazy val output = bindings.getValue("output").asInstanceOf[OutputStream] implicit def outputStream2Resettable(x: OutputStream): Resettable = x.asInstanceOf[Resettable] } 17
  31. 31. Bindings wrapper (cont.) ■ Limitations – Scala’s visibility modifiers not exposed through reflection – Not yet working with parametrized types – Ambiguities in generated implicit conversion 18
  32. 32. Scalac and OSGi ■ Scalac – Requires compiler class path – File system based ■ OSGi – Provides class loaders – Bundle based ■ Bridging the gap – File system abstraction over OSGi bundles – Implement scala.tools.nsc.io.AbstractFile – Limitation: wiring probably not fully respected 19
  33. 33. Independent through configuration ■ Abstract implementation details into configuration class – Default implementation for standalone usage – Specialized implementations for Sling – Set through ScriptEngineFactory or injected via OSGi service lookup X
  34. 34. Configuration ■ Scala compiler – Per script engine – scripting.scala.SettingsProvider – Class and output paths: scala.tools.nsc.io.AbstractFile – Settings: scala.tools.nsc.Settings – Reporting: scala.tools.nsc.reporters.Reporter ■ Script entry point – Per invocation – scripting.scala.ScriptInfo X
  35. 35. Performance ■ On the fly compilation is slow – Cache pre compiled scripts – Dependency on bindings: include bindings wrapper – Work in progress 20
  36. 36. Conclusion ■ Scala is attractive for scripting – Concise and versatile – DSL capabilities – Type safe – XML literals for type safe templating ■ Impedance mismatches – JSR-223: dynamic vs. static typing – OSGi: runtime environment vs. compile time utility – Performance: illusion of executing source code 21
  37. 37. References ■ Scala for Scripting http://people.apache.org/~mduerig/scala4scripting/ ■ Apache Sling http://sling.apache.org/ ■ Michael Dürig michael.duerig@day.com ■ Day Software AG http://www.day.com/ 22
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×