SlideShare una empresa de Scribd logo
1 de 49
Descargar para leer sin conexión
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
SPRINGONE2GX
WASHINGTON, DC
Grooscript in Action
By Jorge Franco Leza
@jfrancoleza
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
About me
2
Developer
jorge.franco.leza@gmail.com
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Thank you!
3
3 years since first commit
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Agenda
• Introduction to grooscript
• Convert your groovy code to javascript
• Support
• PhantomJs and tools
• Gradle plugin
• Demo
• Grails plugin
• Working with javascript
• Require.js
• Future
4
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Introduction to grooscript
• Library (jar)
• Groovy 2.0+ to javascript ECMA 5
• Apache 2 license
• Source code http://github.com/chiquitinxx/grooscript
• Converted code needs grooscript.js to run
• Tools around: gradle and grails plugins, npm and bower packages
• Documentation http://grooscript.org/doc.html
• Demos http://github.com/chiquitinxx/grooscript-demos
• Try live! http://grooscript.org/conversions.html
5
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Why grooscript?
• You have all java / groovy tools to create code in the client side.
• Javascript is fast.
• Enjoy javascript! Create your own magic.
• Don’t repeat code in two languages, isomorphic code.
• Use groovy templates everywhere.
• Single development environment.
• Stop learning “to javascript” things.
• Static type if you want to.
• But… mainly… because it is…
6
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Groovy
7
Readable
Concise
Expressive
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
ASTS
8
@Component

class Counter implements Colorable {



Integer number



void init() {

number = null

}



void render() {

div(class: "widget bg-${randomColor()}") {

if (number) {

p 'Number of books'

em number.toString()

a(href:"#", class:"button",
onclick: 'bookPresenter.showBooks()') {

yield 'Show'

}

} else {

p 'Counting books...'

}

}

}

}
AST’s
Getter / Setters
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
List and maps
9
def start() {
def countries = loadCountries().
findAll { it.population > 100000}.
unique { it.alpha3Code }
countries.each { country ->
customSigma.addNode id: country.alpha3Code,
x: country.latlng[1], color: ‘purple’
}
countries.each { country ->
country.borders?.each { border ->
this.&hello(border)
}
}
updateNumberCountries countries.size()
customSigma.refresh()
}
Lists and maps
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
DSL's
10
server {
get('/') {
render Templates.applyTemplate('index.gtpl')
}
on('login') { data, socket ->
if (data.name && !socket.login) {
socket.login = data.name
socket.emit 'loginok', [name: data.name]
socket.broadcast.emit 'loginok', [name: data.name]
}
}
on('msg') { data, socket ->
if (data.msg && socket.login) {
socket.broadcast.emit 'msg', [msg: data.msg]
}
}
on('disconnect') { socket ->
if (socket.login) {
socket.broadcast.emit 'off', [name: socket.login]
}
}
}.start()
Dsl’s
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Metaprogramming
11
class Hello {
def methodMissing(String name, args) {
println "Hello ${name}!"
}
}
def hello = new Hello()
hello.Groovy()
hello.Javascript()
hello.grooscript()
Metaprogramming
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Functional
12
def plus2 = { it + 2 }
def times3 = { it * 3 }
def times3plus2 = plus2 << times3
assert times3plus2(3) == 11
def plus2times3 = times3 << plus2
assert plus2times3.curry(5)() == 21
Functional
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Convert your groovy code to javascript
13
@Grab('org.grooscript:grooscript:1.2.0')
import org.grooscript.GrooScript
String result = GrooScript.convert '''
def sayHello = { println "Hello ${it}!" }
['Groovy','JavaScript','GrooScript'].each sayHello
'''
new File(‘out.js’) << result
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Convert your groovy code to javascript
14
Let’s see it in action
http://grooscript.org/doc.html
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Conversion options
• classpath
• customization { -> ast(TypeChecked)}
• initialText, finalText
• recursive
• mainContextScope [''$'', ‘'window'', ''myFunction'']
• addGsLib
• requireJsModule
• consoleInfo
• includeDependencies
15
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Support
• Groovy core
• Classes, numbers, lists, maps, sets, date, ranges, closures, (g)strings, operators,
groovy truth, Expando, categories, traits, beans, switch, metaprogramming,
enum, equals, multiple assignment, optional params, default constructor, pointer
methods, operator overload, regular expressions, @Delegate, @Category, …
• Dsl’s. (@DelegatesTo)
• Ast’s at semantic analysis phase.
• Packaging in js with require.js.
• Be groovier!
16
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Not supported
• Not groovy-core (json, builders, I/O, …)
• Java / Groovy Types (Thread, LinkedHashMap, Stack, Optional, …)
• Super except constructors.
• Methods with same name (overload), classes with same name.
• Java 8 stuff not supported by groovy
• Module extensions, complex metaprogramming, groovy AST’s after Semantic
Phase
17
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Annotations
18
import org.grooscript.asts.GsNotConvert
@GsNotConvert
class ClassNotConvert {
def a
}
class A {
@GsNotConvert
def methodNoConvert() {
‘No!’
}
def hello() {
println ‘Hello!’
}
}
import org.grooscript.asts.GsNative
class Data {
@GsNative
void saySomething(String smt) {/*
console.log(smt);
*/}
@GsNative
def five() {/*
return 5;
*/ 1 + 1 + 3
}
}
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
PhantomJs test
19
@GrabConfig(systemClassLoader = true)
@Grab(‘org.grooscript:grooscript:1.2.0’)
import org.grooscript.asts.PhantomJsTest
//Need phantomjs installed
System.setProperty(‘PHANTOMJS_HOME’, ‘path/to/phantomjs’)
@PhantomJsTest(url = 'http://beta.groovy-lang.org/')
void testCountLinks() {
def links = $('a')
assert links.size() > 40, "Number of links: ${links.size()}"
links.toArray().collect { it.toString() }.each { link ->
println link
}
}
testCountLinks()
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Javascript libs
• grooscript.js (87 kb) (8 kb minified and gziped)
• grooscript.min.js (33 kb)
• grooscript-tools.js (14 kb) (GQuery, HtmlBuilder, Observable)
20
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
HtmlBuilder
21
given:
def result = HtmlBuilder.build {
body {
ul(class: 'list', id: 'mainList') {
2.times { number ->
li number + 'Hello!'
}
}
}
}
expect:
result == "<body><ul class='list' id=‘mainList'>
<li>0Hello!</li><li>1Hello!</li></ul></body>"
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
GQuery
22
import org.grooscript.jquery.GQueryImpl
def result = new Result()
def gQuery = new GQueryImpl()
gQuery.onReady {
gQuery.doRemoteCall(“${JSON_ADDRESS}”, 'GET', null, { res ->
gQuery('.result').html('OK')
result = res
}, {
result = 'FAIL!'
}, Result)
}
https://github.com/chiquitinxx/grooscript/blob/master/src/
main/groovy/org/grooscript/jquery/GQuery.groovy
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Observable
23
given:
def result = []
Observable.from([1, 5, 9, 12, 3, 8]).
filter { it < 5 }.
map { 'H' * it }.
subscribe { event ->
result << event
}
expect:
result == ['H', 'HHH']
https://github.com/chiquitinxx/grooscript/blob/master/src/
test/groovy/org/grooscript/rx/ObservableSpec.groovy
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Gradle plugin
• Starting guide http://grooscript.org/starting_gradle.html
• Listen to changes and does conversions in background.
• Groovy templates in the client side.
• Can use with your grails 3+ application.
• Create require.js modules.
• Notification of changes using websockets.
• Thread tasks can block execution.
• Info about tasks http://grooscript.org/gradle/tasks.html
24
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
task convert
Convert groovy files to javascript. Can add conversion options.
25
grooscript {
source = ['src/main/groovy']
destination = 'js'
}
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 26
task convertThread
grooscript {
source = [‘src/main/groovy/presenters']
destination = 'js'
classpath = ['src/groovy']
initialText = '//Converted file'
recursive = true
blockExecution = true
}
Listen to changes in groovy files, and convert them to javascript when modified. Can
block gradle execution.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 27
task initStaticWeb
"## build.gradle
$## src
$## main
"## groovy
% $## Presenter.groovy
$## webapp
"## index.html
$## js
"## app
$## lib
"## grooscript-tools.js
"## grooscript.min.js
$## jquery.min.js
Creates a static web project to starting play with grooscript.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 28
task templatesJs
class Templates {
static Map<String, Closure> templates
static String applyTemplate(String name, model = [:]) {
Closure cl = templates[name]
cl.delegate = model
cl(model)
}
}
Convert groovy templates to a javascript file.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 29
task templatesThread
templates {
templatesPath = 'templates'
templates = ['main.gtpl', 'little/small.tpl']
destinationFile = 'js/Templates.js'
classpath = ['src/groovy']
customTypeChecker = 'aCustomTypeCheckerFile.groovy'
}
Listen to changes in groovy templates and generate a new javascript template file
when something changes. Can block gradle execution.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 30
task spyChanges
spy {
files = ['Templates.js']
onChanges = { list ->
springWebsocketTo 'http://localhost:8080/demo' data
'templates' onChannel '/app/reload'
}
}
Listen to file changes and execute groovy code when files change. Can send a
message using websockets.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 31
task requireJs
requireJs {
sourceFile = 'src/main/groovy/MyApp.groovy'
destinationFolder = 'src/main/resources/web/js/app'
}
Convert groovy file to require.js javascript module. Also all dependencies are
converted.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
task requireJsThread
32
requireJs {
sourceFile = ‘starting/InitialFile.groovy'
classpath = ['src/main/groovy']
destinationFolder = ‘js/app'
blockExecution = true
}
Listen to changes in groovy file or any dependency file, and generate require.js
javascript modules when files change. Also can block execution.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 33
Demo gradle books
More action
https://github.com/chiquitinxx/books-demo
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Grails plugin
• A grails 2 version, 0.8 https://grails.org/plugin/grooscript.
• Grails 3 version, version 1.1.2, documentation http://grooscript.org/grails3-plugin.
• Adding tags for your gsp’s.
• Converting files with gradle plugin in grails 3+.
• Using your domain classes in your gsp’s. *experimental*
• Uses asset pipeline and cache plugins, also jquery for some tags.
• Requires <asset:javascript src="grooscript-grails.js"/>
• Events in your gsp's with groovy.
• Websockets support using spring websockets.
• Templating in your gsp’s with HtmlBuilder.
34
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
grooscript:code
35
<grooscript:code>
[‘groovy’, ‘javascript’].each {
println “Hello $it”
}
</grooscript:code>
<asset:script>
… js code …
</asset:script>
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
grooscript:template
36
<grooscript:template onLoad=“false" functionName=“refreshList">
ul {
data.each { book ->
li {
p 'Id: ' + book.id + ' Name: ' + book.title
}
}
}
</grooscript:template>
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
websockets
37
<grooscript:initSpringWebsocket>
println 'Connected! Websocket is up!’
GrooscriptGrails.sendWebsocketMessage("/app/hello", “Hello!")
</grooscript:initSpringWebsocket>
<grooscript:onServerEvent path="/topic/books" type="Book">
data.each { book ->
$("#helloDiv").append '<p>'+book.coolFormat()+'</p>'
}
</grooscript:onServerEvent>
Use spring websockets in your gsp’s. Have to include client libraries.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
events
38
<grooscript:code>
$(document).ready {
def eventData = 'Application started.'
gsEvents.sendMessage('newEvent', eventData)
gsEvents.onEvent('delete', { book ->
$('#deleteEvent').html 'Deleted ' + book.title
})
}
</grooscript:code>
<grooscript:onEvent name="newEvent">
console.log event
</grooscript:onEvent>
Manage events in the client using groovy.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
grooscript:remoteModel
39
<grooscript:remoteModel domainClass="Book"/>
<grooscript:code>
import rest.Book
Book.list().then { list ->
$('#bookList').html ''
list.each addBook
}
</grooscript:code>
Use your domain classes from your gsp’s. Domain classes annotated with
@Resource, using json.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Demo grails 3
40
Final action
https://github.com/chiquitinxx/circles
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Working with javascript
41
class MyClass {} function MyClass() { … }
var myClass = MyClass();
// NO var myClass = new MyClass();
var myClass = MyClass({prop1: ‘value’, prop2: 12 });
myClass.method();
// NO myClass.metaprogrammingMethod();
myClass.method(numberOrStringOrList);
// beware maps! myClass.method({ a: 1, b: 2 });
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Combine both worlds
42
import static org.grooscript.GrooScript.toJavascript
import static org.grooscript.GrooScript.toGroovy
def map = [x: 1, y: 2]
//point is a javascript object
point.init(map) //[BAD] Passing a groovy object to javascript, can fail
point.init(toJavascript(map)) //[GOOD] You now are passing {x: 1, y: 2}
//point has a method info() that returns a javascript object
def badData = point.info() //[BAD] You will have a 'javascript' object
def goodData = toGroovy(point.info()) //[GOOD] goodData as a 'groovy' object
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Tips
• Keep your groovy code tested.
• If you use @GsNative, keep that code in isolated classes, that can be easy to
mock them.
• Don’t abuse @GsNative, is untested code.
• You can activate debug console info in javascript with gs.consoleInfo = true;
• You can test dom manipulation with jsoup.
• Try to stay functional, don’t abuse ‘this’ or variables from other contexts.
• Curry functions to inject variables rather than expecting them to be available
after callbacks hell.
43
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Require.js
• Javascript file and module loader.
• Can be used in browser, rhino and Node.js environments.
• Optimization using google closure compiler.
44
requirejs.config({
baseUrl: 'jsModules',
paths: {
lib: 'js/lib'
}
});
requirejs(['lib/grooscript.min'], function() {
requirejs(['Initial']);
});
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Require.js
45
import org.grooscript.GrooScript
Map conversionOptions = [classpath: 'src/main/groovy']
GrooScript.convertRequireJs('src/main/groovy/Initial.groovy',
'jsModules', conversionOptions)
define(function() {
function Initial() { … }
return Initial;
});
class Initial {
}
src/main/groovy/Initial.groovy jsModules/Initial.js
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Require.js
46
define(['lib/data'], function (data) {
function Require() {
//..
gSobject.data = data;
//..
return gSobject;
};
return Require;
});
package files
import org.grooscript.asts.RequireJsModule
class Require {
@RequireJsModule(path = 'lib/data')
def data
}
src/main/groovy/files/Require.groovy jsModules/files/Require.js
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Future
47
ECMAScript 2015
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 48
Q & A
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Thank you!
49
Waiting for your feedback and questions from now to Thursday

Más contenido relacionado

La actualidad más candente

Embedding Groovy in a Java Application
Embedding Groovy in a Java ApplicationEmbedding Groovy in a Java Application
Embedding Groovy in a Java ApplicationPaolo Predonzani
 
Apache Groovy: the language and the ecosystem
Apache Groovy: the language and the ecosystemApache Groovy: the language and the ecosystem
Apache Groovy: the language and the ecosystemKostas Saidis
 
Groovy on the shell
Groovy on the shellGroovy on the shell
Groovy on the shellsascha_klein
 
GraphQL IN Golang
GraphQL IN GolangGraphQL IN Golang
GraphQL IN GolangBo-Yi Wu
 
Introduction to Griffon
Introduction to GriffonIntroduction to Griffon
Introduction to GriffonJames Williams
 
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie..."How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...Fwdays
 
2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...
2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...
2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...César Hernández
 
PyCon Korea 2019 REST API Document Generation
PyCon Korea 2019 REST API Document GenerationPyCon Korea 2019 REST API Document Generation
PyCon Korea 2019 REST API Document Generation용선 이
 
Golang Project Layout and Practice
Golang Project Layout and PracticeGolang Project Layout and Practice
Golang Project Layout and PracticeBo-Yi Wu
 
Build microservice with gRPC in golang
Build microservice with gRPC in golangBuild microservice with gRPC in golang
Build microservice with gRPC in golangTing-Li Chou
 
Groovy And Grails Introduction
Groovy And Grails IntroductionGroovy And Grails Introduction
Groovy And Grails IntroductionEric Weimer
 
Understanding how concurrency work in os
Understanding how concurrency work in osUnderstanding how concurrency work in os
Understanding how concurrency work in osGenchiLu1
 
really really really awesome php application with bdd behat and iterfaces
really really really awesome php application with bdd behat and iterfacesreally really really awesome php application with bdd behat and iterfaces
really really really awesome php application with bdd behat and iterfacesGiulio De Donato
 
When third parties stop being polite... and start getting real
When third parties stop being polite... and start getting realWhen third parties stop being polite... and start getting real
When third parties stop being polite... and start getting realCharles Vazac
 
Ratpack - Classy and Compact Groovy Web Apps
Ratpack - Classy and Compact Groovy Web AppsRatpack - Classy and Compact Groovy Web Apps
Ratpack - Classy and Compact Groovy Web AppsJames Williams
 

La actualidad más candente (20)

Embedding Groovy in a Java Application
Embedding Groovy in a Java ApplicationEmbedding Groovy in a Java Application
Embedding Groovy in a Java Application
 
Rest, sockets em golang
Rest, sockets em golangRest, sockets em golang
Rest, sockets em golang
 
Apache Groovy: the language and the ecosystem
Apache Groovy: the language and the ecosystemApache Groovy: the language and the ecosystem
Apache Groovy: the language and the ecosystem
 
Groovy on the shell
Groovy on the shellGroovy on the shell
Groovy on the shell
 
GraphQL IN Golang
GraphQL IN GolangGraphQL IN Golang
GraphQL IN Golang
 
Introduction to Griffon
Introduction to GriffonIntroduction to Griffon
Introduction to Griffon
 
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie..."How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
 
Golang
GolangGolang
Golang
 
2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...
2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...
2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...
 
Griffon @ Svwjug
Griffon @ SvwjugGriffon @ Svwjug
Griffon @ Svwjug
 
PyCon Korea 2019 REST API Document Generation
PyCon Korea 2019 REST API Document GenerationPyCon Korea 2019 REST API Document Generation
PyCon Korea 2019 REST API Document Generation
 
Golang Project Layout and Practice
Golang Project Layout and PracticeGolang Project Layout and Practice
Golang Project Layout and Practice
 
Gradle in 45min
Gradle in 45minGradle in 45min
Gradle in 45min
 
Build microservice with gRPC in golang
Build microservice with gRPC in golangBuild microservice with gRPC in golang
Build microservice with gRPC in golang
 
Groovy And Grails Introduction
Groovy And Grails IntroductionGroovy And Grails Introduction
Groovy And Grails Introduction
 
Understanding how concurrency work in os
Understanding how concurrency work in osUnderstanding how concurrency work in os
Understanding how concurrency work in os
 
really really really awesome php application with bdd behat and iterfaces
really really really awesome php application with bdd behat and iterfacesreally really really awesome php application with bdd behat and iterfaces
really really really awesome php application with bdd behat and iterfaces
 
Go at Openprovider
Go at OpenproviderGo at Openprovider
Go at Openprovider
 
When third parties stop being polite... and start getting real
When third parties stop being polite... and start getting realWhen third parties stop being polite... and start getting real
When third parties stop being polite... and start getting real
 
Ratpack - Classy and Compact Groovy Web Apps
Ratpack - Classy and Compact Groovy Web AppsRatpack - Classy and Compact Groovy Web Apps
Ratpack - Classy and Compact Groovy Web Apps
 

Similar a Grooscript in Action SpringOne2gx 2015

Groovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examplesGroovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examplesGR8Conf
 
Becoming an Advanced Groovy Developer Spring One 2gx 2015
Becoming an Advanced Groovy Developer Spring One 2gx 2015Becoming an Advanced Groovy Developer Spring One 2gx 2015
Becoming an Advanced Groovy Developer Spring One 2gx 2015Tom Henricksen
 
groovy transforms
groovy transformsgroovy transforms
groovy transformsPaul King
 
SpringOne 2GX 2015 - Fullstack Groovy developer
SpringOne 2GX 2015 - Fullstack Groovy developerSpringOne 2GX 2015 - Fullstack Groovy developer
SpringOne 2GX 2015 - Fullstack Groovy developerIván López Martín
 
Migrating from Grails 2 to Grails 3
Migrating from Grails 2 to Grails 3Migrating from Grails 2 to Grails 3
Migrating from Grails 2 to Grails 3Michael Plöd
 
Better Than BASH: Scripting Kotlin
Better Than BASH: Scripting KotlinBetter Than BASH: Scripting Kotlin
Better Than BASH: Scripting KotlinVMware Tanzu
 
Lessons learned from upgrading Thymeleaf
Lessons learned from upgrading ThymeleafLessons learned from upgrading Thymeleaf
Lessons learned from upgrading ThymeleafVMware Tanzu
 
Reactive frontends with RxJS and Angular
Reactive frontends with RxJS and AngularReactive frontends with RxJS and Angular
Reactive frontends with RxJS and AngularVMware Tanzu
 
Not Only Reactive - Data Access with Spring Data
Not Only Reactive - Data Access with Spring DataNot Only Reactive - Data Access with Spring Data
Not Only Reactive - Data Access with Spring DataVMware Tanzu
 
Springone2gx 2015 Cassandra and Grails
Springone2gx 2015 Cassandra and GrailsSpringone2gx 2015 Cassandra and Grails
Springone2gx 2015 Cassandra and GrailsJeff Beck
 
Leveling up your JavaScipt - DrupalJam 2017
Leveling up your JavaScipt - DrupalJam 2017Leveling up your JavaScipt - DrupalJam 2017
Leveling up your JavaScipt - DrupalJam 2017Christian Heilmann
 
Reactive Data Access with Spring Data
Reactive Data Access with Spring DataReactive Data Access with Spring Data
Reactive Data Access with Spring DataVMware Tanzu
 
Under the Hood of Reactive Data Access (1/2)
Under the Hood of Reactive Data Access (1/2)Under the Hood of Reactive Data Access (1/2)
Under the Hood of Reactive Data Access (1/2)VMware Tanzu
 
Zero-config JavaScript apps with RaveJS -- SVCC fall 2014
Zero-config JavaScript apps with RaveJS -- SVCC fall 2014Zero-config JavaScript apps with RaveJS -- SVCC fall 2014
Zero-config JavaScript apps with RaveJS -- SVCC fall 2014John Hann
 
Continuous delivery w projekcie open source - Marcin Stachniuk
Continuous delivery w projekcie open source - Marcin StachniukContinuous delivery w projekcie open source - Marcin Stachniuk
Continuous delivery w projekcie open source - Marcin StachniukMarcinStachniuk
 
New in Spring Framework 5.0: Functional Web Framework
New in Spring Framework 5.0: Functional Web FrameworkNew in Spring Framework 5.0: Functional Web Framework
New in Spring Framework 5.0: Functional Web FrameworkVMware Tanzu
 
Migrating to Angular 5 for Spring Developers
Migrating to Angular 5 for Spring DevelopersMigrating to Angular 5 for Spring Developers
Migrating to Angular 5 for Spring DevelopersGunnar Hillert
 
Migrating to Angular 4 for Spring Developers
Migrating to Angular 4 for Spring Developers Migrating to Angular 4 for Spring Developers
Migrating to Angular 4 for Spring Developers VMware Tanzu
 
[convergese] Adaptive Images in Responsive Web Design
[convergese] Adaptive Images in Responsive Web Design[convergese] Adaptive Images in Responsive Web Design
[convergese] Adaptive Images in Responsive Web DesignChristopher Schmitt
 
Reactor 3.0, a reactive foundation for java 8 and Spring
Reactor 3.0, a reactive foundation for java 8 and SpringReactor 3.0, a reactive foundation for java 8 and Spring
Reactor 3.0, a reactive foundation for java 8 and SpringStéphane Maldini
 

Similar a Grooscript in Action SpringOne2gx 2015 (20)

Groovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examplesGroovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examples
 
Becoming an Advanced Groovy Developer Spring One 2gx 2015
Becoming an Advanced Groovy Developer Spring One 2gx 2015Becoming an Advanced Groovy Developer Spring One 2gx 2015
Becoming an Advanced Groovy Developer Spring One 2gx 2015
 
groovy transforms
groovy transformsgroovy transforms
groovy transforms
 
SpringOne 2GX 2015 - Fullstack Groovy developer
SpringOne 2GX 2015 - Fullstack Groovy developerSpringOne 2GX 2015 - Fullstack Groovy developer
SpringOne 2GX 2015 - Fullstack Groovy developer
 
Migrating from Grails 2 to Grails 3
Migrating from Grails 2 to Grails 3Migrating from Grails 2 to Grails 3
Migrating from Grails 2 to Grails 3
 
Better Than BASH: Scripting Kotlin
Better Than BASH: Scripting KotlinBetter Than BASH: Scripting Kotlin
Better Than BASH: Scripting Kotlin
 
Lessons learned from upgrading Thymeleaf
Lessons learned from upgrading ThymeleafLessons learned from upgrading Thymeleaf
Lessons learned from upgrading Thymeleaf
 
Reactive frontends with RxJS and Angular
Reactive frontends with RxJS and AngularReactive frontends with RxJS and Angular
Reactive frontends with RxJS and Angular
 
Not Only Reactive - Data Access with Spring Data
Not Only Reactive - Data Access with Spring DataNot Only Reactive - Data Access with Spring Data
Not Only Reactive - Data Access with Spring Data
 
Springone2gx 2015 Cassandra and Grails
Springone2gx 2015 Cassandra and GrailsSpringone2gx 2015 Cassandra and Grails
Springone2gx 2015 Cassandra and Grails
 
Leveling up your JavaScipt - DrupalJam 2017
Leveling up your JavaScipt - DrupalJam 2017Leveling up your JavaScipt - DrupalJam 2017
Leveling up your JavaScipt - DrupalJam 2017
 
Reactive Data Access with Spring Data
Reactive Data Access with Spring DataReactive Data Access with Spring Data
Reactive Data Access with Spring Data
 
Under the Hood of Reactive Data Access (1/2)
Under the Hood of Reactive Data Access (1/2)Under the Hood of Reactive Data Access (1/2)
Under the Hood of Reactive Data Access (1/2)
 
Zero-config JavaScript apps with RaveJS -- SVCC fall 2014
Zero-config JavaScript apps with RaveJS -- SVCC fall 2014Zero-config JavaScript apps with RaveJS -- SVCC fall 2014
Zero-config JavaScript apps with RaveJS -- SVCC fall 2014
 
Continuous delivery w projekcie open source - Marcin Stachniuk
Continuous delivery w projekcie open source - Marcin StachniukContinuous delivery w projekcie open source - Marcin Stachniuk
Continuous delivery w projekcie open source - Marcin Stachniuk
 
New in Spring Framework 5.0: Functional Web Framework
New in Spring Framework 5.0: Functional Web FrameworkNew in Spring Framework 5.0: Functional Web Framework
New in Spring Framework 5.0: Functional Web Framework
 
Migrating to Angular 5 for Spring Developers
Migrating to Angular 5 for Spring DevelopersMigrating to Angular 5 for Spring Developers
Migrating to Angular 5 for Spring Developers
 
Migrating to Angular 4 for Spring Developers
Migrating to Angular 4 for Spring Developers Migrating to Angular 4 for Spring Developers
Migrating to Angular 4 for Spring Developers
 
[convergese] Adaptive Images in Responsive Web Design
[convergese] Adaptive Images in Responsive Web Design[convergese] Adaptive Images in Responsive Web Design
[convergese] Adaptive Images in Responsive Web Design
 
Reactor 3.0, a reactive foundation for java 8 and Spring
Reactor 3.0, a reactive foundation for java 8 and SpringReactor 3.0, a reactive foundation for java 8 and Spring
Reactor 3.0, a reactive foundation for java 8 and Spring
 

Último

Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Visualising and forecasting stocks using Dash
Visualising and forecasting stocks using DashVisualising and forecasting stocks using Dash
Visualising and forecasting stocks using Dashnarutouzumaki53779
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 

Último (20)

Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Visualising and forecasting stocks using Dash
Visualising and forecasting stocks using DashVisualising and forecasting stocks using Dash
Visualising and forecasting stocks using Dash
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 

Grooscript in Action SpringOne2gx 2015

  • 1. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ SPRINGONE2GX WASHINGTON, DC Grooscript in Action By Jorge Franco Leza @jfrancoleza
  • 2. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ About me 2 Developer jorge.franco.leza@gmail.com
  • 3. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Thank you! 3 3 years since first commit
  • 4. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Agenda • Introduction to grooscript • Convert your groovy code to javascript • Support • PhantomJs and tools • Gradle plugin • Demo • Grails plugin • Working with javascript • Require.js • Future 4
  • 5. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Introduction to grooscript • Library (jar) • Groovy 2.0+ to javascript ECMA 5 • Apache 2 license • Source code http://github.com/chiquitinxx/grooscript • Converted code needs grooscript.js to run • Tools around: gradle and grails plugins, npm and bower packages • Documentation http://grooscript.org/doc.html • Demos http://github.com/chiquitinxx/grooscript-demos • Try live! http://grooscript.org/conversions.html 5
  • 6. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Why grooscript? • You have all java / groovy tools to create code in the client side. • Javascript is fast. • Enjoy javascript! Create your own magic. • Don’t repeat code in two languages, isomorphic code. • Use groovy templates everywhere. • Single development environment. • Stop learning “to javascript” things. • Static type if you want to. • But… mainly… because it is… 6
  • 7. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Groovy 7 Readable Concise Expressive
  • 8. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ ASTS 8 @Component
 class Counter implements Colorable {
 
 Integer number
 
 void init() {
 number = null
 }
 
 void render() {
 div(class: "widget bg-${randomColor()}") {
 if (number) {
 p 'Number of books'
 em number.toString()
 a(href:"#", class:"button", onclick: 'bookPresenter.showBooks()') {
 yield 'Show'
 }
 } else {
 p 'Counting books...'
 }
 }
 }
 } AST’s Getter / Setters
  • 9. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ List and maps 9 def start() { def countries = loadCountries(). findAll { it.population > 100000}. unique { it.alpha3Code } countries.each { country -> customSigma.addNode id: country.alpha3Code, x: country.latlng[1], color: ‘purple’ } countries.each { country -> country.borders?.each { border -> this.&hello(border) } } updateNumberCountries countries.size() customSigma.refresh() } Lists and maps
  • 10. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ DSL's 10 server { get('/') { render Templates.applyTemplate('index.gtpl') } on('login') { data, socket -> if (data.name && !socket.login) { socket.login = data.name socket.emit 'loginok', [name: data.name] socket.broadcast.emit 'loginok', [name: data.name] } } on('msg') { data, socket -> if (data.msg && socket.login) { socket.broadcast.emit 'msg', [msg: data.msg] } } on('disconnect') { socket -> if (socket.login) { socket.broadcast.emit 'off', [name: socket.login] } } }.start() Dsl’s
  • 11. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Metaprogramming 11 class Hello { def methodMissing(String name, args) { println "Hello ${name}!" } } def hello = new Hello() hello.Groovy() hello.Javascript() hello.grooscript() Metaprogramming
  • 12. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Functional 12 def plus2 = { it + 2 } def times3 = { it * 3 } def times3plus2 = plus2 << times3 assert times3plus2(3) == 11 def plus2times3 = times3 << plus2 assert plus2times3.curry(5)() == 21 Functional
  • 13. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Convert your groovy code to javascript 13 @Grab('org.grooscript:grooscript:1.2.0') import org.grooscript.GrooScript String result = GrooScript.convert ''' def sayHello = { println "Hello ${it}!" } ['Groovy','JavaScript','GrooScript'].each sayHello ''' new File(‘out.js’) << result
  • 14. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Convert your groovy code to javascript 14 Let’s see it in action http://grooscript.org/doc.html
  • 15. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Conversion options • classpath • customization { -> ast(TypeChecked)} • initialText, finalText • recursive • mainContextScope [''$'', ‘'window'', ''myFunction''] • addGsLib • requireJsModule • consoleInfo • includeDependencies 15
  • 16. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Support • Groovy core • Classes, numbers, lists, maps, sets, date, ranges, closures, (g)strings, operators, groovy truth, Expando, categories, traits, beans, switch, metaprogramming, enum, equals, multiple assignment, optional params, default constructor, pointer methods, operator overload, regular expressions, @Delegate, @Category, … • Dsl’s. (@DelegatesTo) • Ast’s at semantic analysis phase. • Packaging in js with require.js. • Be groovier! 16
  • 17. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Not supported • Not groovy-core (json, builders, I/O, …) • Java / Groovy Types (Thread, LinkedHashMap, Stack, Optional, …) • Super except constructors. • Methods with same name (overload), classes with same name. • Java 8 stuff not supported by groovy • Module extensions, complex metaprogramming, groovy AST’s after Semantic Phase 17
  • 18. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Annotations 18 import org.grooscript.asts.GsNotConvert @GsNotConvert class ClassNotConvert { def a } class A { @GsNotConvert def methodNoConvert() { ‘No!’ } def hello() { println ‘Hello!’ } } import org.grooscript.asts.GsNative class Data { @GsNative void saySomething(String smt) {/* console.log(smt); */} @GsNative def five() {/* return 5; */ 1 + 1 + 3 } }
  • 19. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ PhantomJs test 19 @GrabConfig(systemClassLoader = true) @Grab(‘org.grooscript:grooscript:1.2.0’) import org.grooscript.asts.PhantomJsTest //Need phantomjs installed System.setProperty(‘PHANTOMJS_HOME’, ‘path/to/phantomjs’) @PhantomJsTest(url = 'http://beta.groovy-lang.org/') void testCountLinks() { def links = $('a') assert links.size() > 40, "Number of links: ${links.size()}" links.toArray().collect { it.toString() }.each { link -> println link } } testCountLinks()
  • 20. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Javascript libs • grooscript.js (87 kb) (8 kb minified and gziped) • grooscript.min.js (33 kb) • grooscript-tools.js (14 kb) (GQuery, HtmlBuilder, Observable) 20
  • 21. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ HtmlBuilder 21 given: def result = HtmlBuilder.build { body { ul(class: 'list', id: 'mainList') { 2.times { number -> li number + 'Hello!' } } } } expect: result == "<body><ul class='list' id=‘mainList'> <li>0Hello!</li><li>1Hello!</li></ul></body>"
  • 22. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ GQuery 22 import org.grooscript.jquery.GQueryImpl def result = new Result() def gQuery = new GQueryImpl() gQuery.onReady { gQuery.doRemoteCall(“${JSON_ADDRESS}”, 'GET', null, { res -> gQuery('.result').html('OK') result = res }, { result = 'FAIL!' }, Result) } https://github.com/chiquitinxx/grooscript/blob/master/src/ main/groovy/org/grooscript/jquery/GQuery.groovy
  • 23. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Observable 23 given: def result = [] Observable.from([1, 5, 9, 12, 3, 8]). filter { it < 5 }. map { 'H' * it }. subscribe { event -> result << event } expect: result == ['H', 'HHH'] https://github.com/chiquitinxx/grooscript/blob/master/src/ test/groovy/org/grooscript/rx/ObservableSpec.groovy
  • 24. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Gradle plugin • Starting guide http://grooscript.org/starting_gradle.html • Listen to changes and does conversions in background. • Groovy templates in the client side. • Can use with your grails 3+ application. • Create require.js modules. • Notification of changes using websockets. • Thread tasks can block execution. • Info about tasks http://grooscript.org/gradle/tasks.html 24
  • 25. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ task convert Convert groovy files to javascript. Can add conversion options. 25 grooscript { source = ['src/main/groovy'] destination = 'js' }
  • 26. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 26 task convertThread grooscript { source = [‘src/main/groovy/presenters'] destination = 'js' classpath = ['src/groovy'] initialText = '//Converted file' recursive = true blockExecution = true } Listen to changes in groovy files, and convert them to javascript when modified. Can block gradle execution.
  • 27. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 27 task initStaticWeb "## build.gradle $## src $## main "## groovy % $## Presenter.groovy $## webapp "## index.html $## js "## app $## lib "## grooscript-tools.js "## grooscript.min.js $## jquery.min.js Creates a static web project to starting play with grooscript.
  • 28. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 28 task templatesJs class Templates { static Map<String, Closure> templates static String applyTemplate(String name, model = [:]) { Closure cl = templates[name] cl.delegate = model cl(model) } } Convert groovy templates to a javascript file.
  • 29. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 29 task templatesThread templates { templatesPath = 'templates' templates = ['main.gtpl', 'little/small.tpl'] destinationFile = 'js/Templates.js' classpath = ['src/groovy'] customTypeChecker = 'aCustomTypeCheckerFile.groovy' } Listen to changes in groovy templates and generate a new javascript template file when something changes. Can block gradle execution.
  • 30. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 30 task spyChanges spy { files = ['Templates.js'] onChanges = { list -> springWebsocketTo 'http://localhost:8080/demo' data 'templates' onChannel '/app/reload' } } Listen to file changes and execute groovy code when files change. Can send a message using websockets.
  • 31. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 31 task requireJs requireJs { sourceFile = 'src/main/groovy/MyApp.groovy' destinationFolder = 'src/main/resources/web/js/app' } Convert groovy file to require.js javascript module. Also all dependencies are converted.
  • 32. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ task requireJsThread 32 requireJs { sourceFile = ‘starting/InitialFile.groovy' classpath = ['src/main/groovy'] destinationFolder = ‘js/app' blockExecution = true } Listen to changes in groovy file or any dependency file, and generate require.js javascript modules when files change. Also can block execution.
  • 33. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 33 Demo gradle books More action https://github.com/chiquitinxx/books-demo
  • 34. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Grails plugin • A grails 2 version, 0.8 https://grails.org/plugin/grooscript. • Grails 3 version, version 1.1.2, documentation http://grooscript.org/grails3-plugin. • Adding tags for your gsp’s. • Converting files with gradle plugin in grails 3+. • Using your domain classes in your gsp’s. *experimental* • Uses asset pipeline and cache plugins, also jquery for some tags. • Requires <asset:javascript src="grooscript-grails.js"/> • Events in your gsp's with groovy. • Websockets support using spring websockets. • Templating in your gsp’s with HtmlBuilder. 34
  • 35. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ grooscript:code 35 <grooscript:code> [‘groovy’, ‘javascript’].each { println “Hello $it” } </grooscript:code> <asset:script> … js code … </asset:script>
  • 36. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ grooscript:template 36 <grooscript:template onLoad=“false" functionName=“refreshList"> ul { data.each { book -> li { p 'Id: ' + book.id + ' Name: ' + book.title } } } </grooscript:template>
  • 37. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ websockets 37 <grooscript:initSpringWebsocket> println 'Connected! Websocket is up!’ GrooscriptGrails.sendWebsocketMessage("/app/hello", “Hello!") </grooscript:initSpringWebsocket> <grooscript:onServerEvent path="/topic/books" type="Book"> data.each { book -> $("#helloDiv").append '<p>'+book.coolFormat()+'</p>' } </grooscript:onServerEvent> Use spring websockets in your gsp’s. Have to include client libraries.
  • 38. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ events 38 <grooscript:code> $(document).ready { def eventData = 'Application started.' gsEvents.sendMessage('newEvent', eventData) gsEvents.onEvent('delete', { book -> $('#deleteEvent').html 'Deleted ' + book.title }) } </grooscript:code> <grooscript:onEvent name="newEvent"> console.log event </grooscript:onEvent> Manage events in the client using groovy.
  • 39. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ grooscript:remoteModel 39 <grooscript:remoteModel domainClass="Book"/> <grooscript:code> import rest.Book Book.list().then { list -> $('#bookList').html '' list.each addBook } </grooscript:code> Use your domain classes from your gsp’s. Domain classes annotated with @Resource, using json.
  • 40. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Demo grails 3 40 Final action https://github.com/chiquitinxx/circles
  • 41. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Working with javascript 41 class MyClass {} function MyClass() { … } var myClass = MyClass(); // NO var myClass = new MyClass(); var myClass = MyClass({prop1: ‘value’, prop2: 12 }); myClass.method(); // NO myClass.metaprogrammingMethod(); myClass.method(numberOrStringOrList); // beware maps! myClass.method({ a: 1, b: 2 });
  • 42. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Combine both worlds 42 import static org.grooscript.GrooScript.toJavascript import static org.grooscript.GrooScript.toGroovy def map = [x: 1, y: 2] //point is a javascript object point.init(map) //[BAD] Passing a groovy object to javascript, can fail point.init(toJavascript(map)) //[GOOD] You now are passing {x: 1, y: 2} //point has a method info() that returns a javascript object def badData = point.info() //[BAD] You will have a 'javascript' object def goodData = toGroovy(point.info()) //[GOOD] goodData as a 'groovy' object
  • 43. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Tips • Keep your groovy code tested. • If you use @GsNative, keep that code in isolated classes, that can be easy to mock them. • Don’t abuse @GsNative, is untested code. • You can activate debug console info in javascript with gs.consoleInfo = true; • You can test dom manipulation with jsoup. • Try to stay functional, don’t abuse ‘this’ or variables from other contexts. • Curry functions to inject variables rather than expecting them to be available after callbacks hell. 43
  • 44. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Require.js • Javascript file and module loader. • Can be used in browser, rhino and Node.js environments. • Optimization using google closure compiler. 44 requirejs.config({ baseUrl: 'jsModules', paths: { lib: 'js/lib' } }); requirejs(['lib/grooscript.min'], function() { requirejs(['Initial']); });
  • 45. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Require.js 45 import org.grooscript.GrooScript Map conversionOptions = [classpath: 'src/main/groovy'] GrooScript.convertRequireJs('src/main/groovy/Initial.groovy', 'jsModules', conversionOptions) define(function() { function Initial() { … } return Initial; }); class Initial { } src/main/groovy/Initial.groovy jsModules/Initial.js
  • 46. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Require.js 46 define(['lib/data'], function (data) { function Require() { //.. gSobject.data = data; //.. return gSobject; }; return Require; }); package files import org.grooscript.asts.RequireJsModule class Require { @RequireJsModule(path = 'lib/data') def data } src/main/groovy/files/Require.groovy jsModules/files/Require.js
  • 47. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Future 47 ECMAScript 2015
  • 48. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 48 Q & A
  • 49. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Thank you! 49 Waiting for your feedback and questions from now to Thursday