relproxy, easy class reload and scripting with java

62
RelProxy Easy Class Reload and Scripting with Java Jose María Arranz Santamaría January 28, 2015

Upload: jose-maria-arranz

Post on 16-Jul-2015

464 views

Category:

Software


0 download

TRANSCRIPT

Page 1: RelProxy, Easy Class Reload and Scripting with Java

RelProxy

Easy Class Reload

and Scripting with Java

Jose María Arranz Santamaría January 28, 2015

Page 2: RelProxy, Easy Class Reload and Scripting with Java

RelProxy...

● WHAT IS?

● WHY?

● HOW IT WORKS…

● WHERE?

Page 3: RelProxy, Easy Class Reload and Scripting with Java

WHAT IS?

Page 4: RelProxy, Easy Class Reload and Scripting with Java

What is?

● A simple Java and Groovy automatic class reloader

from sourceo In development … and production if you want

● Converts pure Java on the fastest scripting languageo Compiling on demand, not a new language like BeanShell

o Including an interactive shell

Page 5: RelProxy, Easy Class Reload and Scripting with Java

WHY?

Page 6: RelProxy, Easy Class Reload and Scripting with Java

ENVY!!!

Page 7: RelProxy, Easy Class Reload and Scripting with Java

Why?

● Envy of Groovy’s “false” scripting

● Groovy is NOT really a scripting/interpreted language, it

“just” compiles on the fly to conventional Java bytecodeo More correctly Groovy is a dynamic language

● I realized this when making an example of embedding

Groovy on ItsNat web framework

Page 8: RelProxy, Easy Class Reload and Scripting with Java

Why?

● Envy for automatic class reload of other web

frameworks & dynamic langs with just a page reload

● Auto context reloading (Tomcat etc) is TEDIOUSo Everything is reloaded per file save => slowing all and PermGen

o Session is lost, start again and again

● ItsNat, a Java based web framework, asked his father

for support of automatic class reloading o It suffers of “me too” syndrome

o Very soon I realized it could be an independent project

Page 9: RelProxy, Easy Class Reload and Scripting with Java

HOW IT WORKS

Page 10: RelProxy, Easy Class Reload and Scripting with Java

How it works

● The Java Reload Proxy

● A shell scripting language named Java

● JSR-223 Java Scripting API

● Bonus: Groovy loves Java. The Groovy Reload Proxy

Page 11: RelProxy, Easy Class Reload and Scripting with Java

The Java Reload Proxy

Page 12: RelProxy, Easy Class Reload and Scripting with Java

The Java Reload Proxy

GOAL:

Automatic recompile and reload changed source

files/classes in web with a simple page reload

WITHOUT CONTEXT RELOADING!!

DISABLE IT!! => read the Manual

Page 13: RelProxy, Easy Class Reload and Scripting with Java

The Java Reload Proxy

InvocationHandler

VersionedObject Object

JProxyEngine

Change

Detector And

Compiler

Class

Reloader

java.lang.ref

lect.Proxy

public

method

invoked

ask

reload

needed

reload

JProxyClass

Loader

new

instance

versioned

method

called

Page 14: RelProxy, Easy Class Reload and Scripting with Java

The Java Reload Proxy

● Advantages over JVM HotSwap in Debugo JVM standard HotSwap is limited to change method bodies

RelProxy/JProxy gives you more freedom, even add new classes

● Advantages over Context Reloadingo Context Reloading reloads ANYTHING

RelProxy only loads a subset of your code

o In CR session is lost

o In CR, in practice, reloading happens per file save

Page 15: RelProxy, Easy Class Reload and Scripting with Java

The Java Reload Proxy

● Everything cannot and should not be reloadedo Server state must be kept when source code is changed

o Reloading data hold by singletons is dangerous

● Stateless/functional classes are candidates for

reloadingo In ItsNat, code doing page load/event rendering on request, that is

code dependent from ItsNatServletRequestListener

o The method public void processRequest(ItsNatServletRequest request,ItsNatServletResponse response)

o is called on page load time

Page 16: RelProxy, Easy Class Reload and Scripting with Java

The Java Reload Proxypackage example.javaex;

import org.itsnat.core.event.ItsNatServletRequestListener;

import org.itsnat.core.ItsNatServletRequest;

import org.itsnat.core.ItsNatServletResponse;

import org.itsnat.core.html.ItsNatHTMLDocument;

public class JProxyExampleLoadListener implements ItsNatServletRequestListener

{

protected FalseDB db;

public JProxyExampleLoadListener() { }

public JProxyExampleLoadListener(FalseDB db) { this.db = db; }

public void processRequest(ItsNatServletRequest request, ItsNatServletResponse response)

{

System.out.println("JProxyExampleLoadListener 1 " + this.getClass().getClassLoader().hashCode());

new example.javaex.JProxyExampleDocument(request,(ItsNatHTMLDocument)request.getItsNatDocument(),db);

}

}

Page 17: RelProxy, Easy Class Reload and Scripting with Java

The Java Reload Proxy

FalseDB db = new FalseDB();

String pathPrefix = context.getRealPath("/") + "/WEB-INF/jproxyex/pages/";

ItsNatDocumentTemplate docTemplate;

docTemplate = itsNatServlet.registerItsNatDocumentTemplate("jproxyex","text/html",

pathPrefix + "jproxyex.html");

ItsNatServletRequestListener listener = new example.javaex.JProxyExampleLoadListener(db);

docTemplate.addItsNatServletRequestListener(listener);

● In a conventional ItsNat web application, JProxyExampleLoadListener is a singleton

registered with something like this:

Page 18: RelProxy, Easy Class Reload and Scripting with Java

The Java Reload Proxy

public void processRequest(ItsNatServletRequest request, ItsNatServletResponse response)

{

System.out.println("JProxyExampleLoadListener 10 " + this.getClass().getClassLoader().hashCode());

new example.javaex.JProxyExampleDocument(request,(ItsNatHTMLDocument)request.getItsNatDocument(),db);

}

● Remember the JProxyExampleLoadListener code:

● If we are able of reloading JProxyExampleLoadListener we are also able to fully reload

JProxyExampleDocument and dependent code on a page load =>VIEW LOGIC RELOADED

Every page reload

creates a new instance

Page 19: RelProxy, Easy Class Reload and Scripting with Java

The Java Reload Proxy

Because JProxyExampleLoadListener is a singleton

we can reload the code => fields must not change (state)

Q) How can we detect source code changes of the

singleton class and related classes and apply them in real

time?

A) Registering a proxy instead of the original singleton,

when a method is called, it is performed on the proxy

instead of the original Java object => reload classesThis is why com.innowhere.relproxy.jproxy.JProxy exists

Page 20: RelProxy, Easy Class Reload and Scripting with Java

The Java Reload Proxy

package example.javaex;

import java.io.File;

import java.lang.reflect.Method;

import java.util.Arrays;

import java.util.List;

import javax.servlet.*;

import javax.tools.Diagnostic;

import javax.tools.DiagnosticCollector;

import javax.tools.JavaFileObject;

import org.itsnat.core.event.ItsNatServletRequestListener;

import org.itsnat.core.http.HttpServletWrapper;

● Configuration in the servleto Part of this code can be put in a ServletContextListener

Page 21: RelProxy, Easy Class Reload and Scripting with Java

The Java Reload Proxy

import org.itsnat.core.tmpl.ItsNatDocumentTemplate;

import com.innowhere.relproxy.RelProxyOnReloadListener;

import com.innowhere.relproxy.jproxy.*;

public class JProxyExampleServlet extends HttpServletWrapper

{

public JProxyExampleServlet() { }

@Override

public void init(ServletConfig config) throws ServletException

{

super.init(config);

ServletContext context = getServletContext();

String realPath = context.getRealPath("/");

String inputPath = realPath + "/WEB-INF/javaex/code/";

String classFolder = null; // Optional: context.getRealPath("/") + "/WEB-INF/classes";

Iterable<String> compilationOptions = Arrays.asList(new String[]{"-source","1.6","-target","1.6"});

long scanPeriod = 300;

JProxy config params

Java sources to reload

are here!!

Page 22: RelProxy, Easy Class Reload and Scripting with Java

The Java Reload Proxy

RelProxyOnReloadListener proxyListener = new RelProxyOnReloadListener() {

@Override

public void onReload(Object objOld, Object objNew, Object proxy, Method method, Object[] args) {

System.out.println("Reloaded " + objNew + " Calling method: " + method);

}

};

JProxyInputSourceFileExcludedListener excludedListener = new JProxyInputSourceFileExcludedListener() {

@Override

public boolean isExcluded(File file, File rootFolderOfSources) { return false; }

};

JProxyCompilerListener compilerListener = new JProxyCompilerListener(){

@Override

public void beforeCompile(File file) { System.out.println("Before compile: " + file); }

@Override

public void afterCompile(File file) { System.out.println("After compile: " + file); }

};

Listener monitor of class

reloading

Listener monitor of file

compiling

Filter for excluding files

of reloading

Page 23: RelProxy, Easy Class Reload and Scripting with Java

The Java Reload ProxyJProxyDiagnosticsListener diagnosticsListener = new JProxyDiagnosticsListener() {

@Override

public void onDiagnostics(DiagnosticCollector<JavaFileObject> diagnostics) {

List<Diagnostic<? extends JavaFileObject>> diagList = diagnostics.getDiagnostics();

int i = 1;

for (Diagnostic<? extends JavaFileObject> diagnostic : diagList) {

System.err.println("Diagnostic " + i);

System.err.println(" code: " + diagnostic.getCode());

System.err.println(" kind: " + diagnostic.getKind());

System.err.println(" line number: " + diagnostic.getLineNumber());

System.err.println(" column number: " + diagnostic.getColumnNumber());

System.err.println(" start position: " + diagnostic.getStartPosition());

System.err.println(" position: " + diagnostic.getPosition());

System.err.println(" end position: " + diagnostic.getEndPosition());

System.err.println(" source: " + diagnostic.getSource());

System.err.println(" message: " + diagnostic.getMessage(null));

i++;

}

}

};

Page 24: RelProxy, Easy Class Reload and Scripting with Java

The Java Reload Proxy

JProxyConfig jpConfig = JProxy.createJProxyConfig();

jpConfig.setEnabled(true)

.setRelProxyOnReloadListener(proxyListener)

.setInputPath(inputPath)

.setJProxyInputSourceFileExcludedListener(excludedListener)

.setScanPeriod(scanPeriod)

.setClassFolder(classFolder)

.setCompilationOptions(compilationOptions)

.setJProxyCompilerListener(compilerListener)

.setJProxyDiagnosticsListener(diagnosticsListener);

JProxy.init(jpConfig);

Configuring JProxy library

Efective configuration

Page 25: RelProxy, Easy Class Reload and Scripting with Java

The Java Reload Proxy

String pathPrefix = context.getRealPath("/") + "/WEB-INF/javaex/pages/";

ItsNatDocumentTemplate docTemplate;

docTemplate = itsNatServlet.registerItsNatDocumentTemplate("javaex","text/html",

pathPrefix + "javaex.html");

FalseDB db = new FalseDB();

ItsNatServletRequestListener listener = JProxy.create(

new example.javaex.JProxyExampleLoadListener(db),ItsNatServletRequestListener.class);

docTemplate.addItsNatServletRequestListener(listener);

}

}

Registers ItsNat HTML

template

Proxy creation wrapping

the load listener singletonRegistering the load listener

singleton associated to the

template

Page 26: RelProxy, Easy Class Reload and Scripting with Java

The Java Reload Proxy

● FalseDB and related are not reloaded in this exampleo It is not proxied and is an external dependency

● Just calling setEnabled(false) in production and

performance impact is ZERO

● JProxy is ItsNat agnostico In spite of previous example is based on ItsNat

● JProxy can be used in similar use cases in your Java

projecto Web or not web

Page 27: RelProxy, Easy Class Reload and Scripting with Java

WHO THE FUCK

IS USING

ITSNAT !!!

Page 28: RelProxy, Easy Class Reload and Scripting with Java

https://groups.google.com/forum/#!topic/itsnat/CO8Qd-Am3L0

Page 29: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you

in development time,

a GWT example

Page 30: RelProxy, Easy Class Reload and Scripting with Java

YES…

GWT !!

Page 31: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT example

● We can define normal Java source code folders as

reloadableo No need of source code below WEB-INF/

o No need to publish source code in production

o Of course this is NOT valid for production

● We will show this feature through a GWT-RPC example

● Download and install Eclipse (Luna is supposed) and

Google Plugin for Eclipse

● Create a GWT-RPC projecto Select New/Other/Google/Web Application Project

o Add relproxy-x.y.z.jar to WEB-INF/lib

Page 32: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT example

● Structure generatedo Name/package relproxy_ex_gwt/com.innowhere.relproxyexgwt

relproxy_ex_gwt (root folder of project)

src/com/innowhere/relproxyexgwt

client

GreetingService.java

GreetingServiceAsync.java

Relproxy_ex_gwt.java

server

GreetingServiceImpl.java

shared

FieldVerifier.java

Relproxy_ex_gwt.gwt.xml

Page 33: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT example

● We are only be able to reload classes executed in servero Classes below server/ folder

o That is, the servlet GreetingServiceImpl.java

● Initial code of GreetingServiceImpl

package com.innowhere.relproxyexgwt.server;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import com.innowhere.relproxyexgwt.client.GreetingService;

import com.innowhere.relproxyexgwt.shared.FieldVerifier;

/**

* The server side implementation of the RPC service.

*/

@SuppressWarnings("serial")

public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService {

Page 34: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT examplepublic String greetServer(String input) throws IllegalArgumentException {

// Verify that the input is valid.

if (!FieldVerifier.isValidName(input)) {

// If the input is not valid, throw an IllegalArgumentException back to

// the client.

throw new IllegalArgumentException("Name must be at least 4 characters long");

}

String serverInfo = getServletContext().getServerInfo();

String userAgent = getThreadLocalRequest().getHeader("User-Agent");

// Escape data from the client to avoid cross-site script vulnerabilities.

input = escapeHtml(input);

userAgent = escapeHtml(userAgent);

return "Hello, " + input + "!<br><br>I am running " + serverInfo +

".<br><br>It looks like you are using:<br>" + userAgent;

}

Page 35: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT example

/**

* Escape an html string. Escaping data received from the client helps to

* prevent cross-site script vulnerabilities.

*

* @param html the html string to escape

* @return the escaped string

*/

private String escapeHtml(String html) {

if (html == null) {

return null;

}

return html.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");

}

}

● Converted to use JProxy...

Page 36: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT example

package com.innowhere.relproxyexgwt.server;

import java.io.File;

import java.lang.reflect.Method;

import java.util.*;

import javax.servlet.*;

import javax.servlet.http.HttpServletRequest;

import javax.tools.*;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import com.innowhere.relproxy.RelProxyOnReloadListener;

import com.innowhere.relproxy.jproxy.*;

import com.innowhere.relproxyexgwt.client.GreetingService;

/**

* The server-side implementation of the RPC service.

*/

@SuppressWarnings("serial")

public class GreetingServiceImpl extends RemoteServiceServlet implements

GreetingService {

Page 37: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT example

protected GreetingServiceDelegate delegate;

public void init(ServletConfig config) throws ServletException {

super.init(config);

ServletContext context = config.getServletContext();

String inputPath = context.getRealPath("/") + "/../src/";

JProxyInputSourceFileExcludedListener excludedListener =

new JProxyInputSourceFileExcludedListener() {

@Override

public boolean isExcluded(File file, File rootFolder) {

String absPath = file.getAbsolutePath();

if (file.isDirectory()) return absPath.endsWith(File.separatorChar + "client") ||

absPath.endsWith(File.separatorChar + "shared");

else return absPath.endsWith(GreetingServiceDelegate.class.getSimpleName() + ".java") ||

absPath.endsWith(GreetingServiceImpl.class.getSimpleName() + ".java");

}

};

Your source !!

Folders excluded

Concrete files excluded

Page 38: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT example

String classFolder = null; // Optional: context.getRealPath("/") + "/WEB-INF/classes";

Iterable<String> compilationOptions =

Arrays.asList(new String[]{"-source","1.6","-target","1.6"});

long scanPeriod = 300;

RelProxyOnReloadListener proxyListener = new RelProxyOnReloadListener() {

public void onReload(Object objOld,Object objNew,Object proxy,Method method,Object[] args){

System.out.println("Reloaded " + objNew + " Calling method: " + method);

}

};

JProxyCompilerListener compilerListener = new JProxyCompilerListener(){

public void beforeCompile(File file) {

System.out.println("Before compile: " + file);

}

public void afterCompile(File file) {

System.out.println("After compile: " + file);

}

};

Page 39: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT example

JProxyDiagnosticsListener diagnosticsListener = new JProxyDiagnosticsListener() {

public void onDiagnostics(DiagnosticCollector<JavaFileObject> diagnostics) {

List<Diagnostic<? extends JavaFileObject>> diagList = diagnostics.getDiagnostics();

int i = 1;

for (Diagnostic diagnostic : diagList) {

System.err.println("Diagnostic " + i);

System.err.println(" code: " + diagnostic.getCode());

System.err.println(" kind: " + diagnostic.getKind());

System.err.println(" line number: " + diagnostic.getLineNumber());

System.err.println(" column number: " + diagnostic.getColumnNumber());

System.err.println(" start position: " + diagnostic.getStartPosition());

System.err.println(" position: " + diagnostic.getPosition());

System.err.println(" end position: " + diagnostic.getEndPosition());

System.err.println(" source: " + diagnostic.getSource());

System.err.println(" message: " + diagnostic.getMessage(null));

i++;

}

}

};

Page 40: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT example

JProxyConfig jpConfig = JProxy.createJProxyConfig();

jpConfig.setEnabled(true)

.setRelProxyOnReloadListener(proxyListener)

.setInputPath(inputPath)

.setJProxyInputSourceFileExcludedListener(excludedListener)

.setScanPeriod(scanPeriod)

.setClassFolder(classFolder)

.setCompilationOptions(compilationOptions)

.setJProxyCompilerListener(compilerListener)

.setJProxyDiagnosticsListener(diagnosticsListener);

JProxy.init(jpConfig);

this.delegate = JProxy.create(

new GreetingServiceDelegateImpl(this),GreetingServiceDelegate.class);

} // init

Page 41: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT example

public String greetServer(String input) throws IllegalArgumentException {

try {

return delegate.greetServer(input);

}

catch(IllegalArgumentException ex) {

ex.printStackTrace();

throw ex;

}

catch(Exception ex) {

ex.printStackTrace();

throw new RuntimeException(ex);

}

}

public HttpServletRequest getThreadLocalRequestPublic() {

return getThreadLocalRequest();

}

}

Page 42: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT example

● GreetingServiceImpl is a servlet, therefore a

singleton in practice, we cannot reload this singleton

● This is why we have moved the code to GreetingServiceDelegateImplo implementing the interface GreetingServiceDelegate

● This new delegation singleton is registered on JProxy

and can be reloadedthis.delegate = JProxy.create(

new GreetingServiceDelegateImpl(this),GreetingServiceDelegate.class);

Page 43: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT example

● When a source change is detected JProxy needs to

reload dependent classes in a new class loader ● But the servlet GreetingServiceImpl cannot be

reloaded, neither client and shared classes, nor

GreetingServiceDelegate => EXCLUDED

public boolean isExcluded(File file, File rootFolder) {

String absPath = file.getAbsolutePath();

if (file.isDirectory()) return absPath.endsWith(File.separatorChar + "client") ||

absPath.endsWith(File.separatorChar + "shared");

else return absPath.endsWith(GreetingServiceDelegate.class.getSimpleName() + ".java") ||

absPath.endsWith(GreetingServiceImpl.class.getSimpleName() + ".java");

}

Page 44: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT example

● GreetingServiceDelegateImpl is basically the

same as the original servlet generated

package com.innowhere.relproxyexgwt.server;

import com.innowhere.relproxyexgwt.shared.FieldVerifier;

public class GreetingServiceDelegateImpl implements GreetingServiceDelegate

{

protected GreetingServiceImpl parent;

public GreetingServiceDelegateImpl() { } // Needed by JProxy

public GreetingServiceDelegateImpl(GreetingServiceImpl parent) {

this.parent = parent;

}

Page 45: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT examplepublic String greetServer(String input) throws IllegalArgumentException {

// Verify that the input is valid.

if (!FieldVerifier.isValidName(input)) {

throw new IllegalArgumentException("Name must be at least 4 characters long");

}

String serverInfo = parent.getServletContext().getServerInfo();

String userAgent = parent.getThreadLocalRequestPublic().getHeader("User-Agent");

input = escapeHtml(input);

userAgent = escapeHtml(userAgent);

return "Hello, " + input + "!<br><br>I am running " + serverInfo

+ ".<br><br>It looks like you are using:<br>" + userAgent;

}

private String escapeHtml(String html) {

if (html == null) { return null; }

return html.replaceAll("&", "&amp;").replaceAll("<", "&lt;")

.replaceAll(">", "&gt;");

}

}

Page 46: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT example

● Run this example o Run As / Web Application / GWT Super Dev Mode

● Open http://127.0.0.1:8888/Relproxy_ex_gwt.html

Page 47: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT example

Page 48: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT example

● Click on the “Close” button ● Modify in Eclipse GreetingServiceDelegateImpl

o just change "Hello" by "Hello <b>BROTHER</b>" and save:

return "Hello <b>BROTHER</b>, " + input + "!<br><br>I am running " + serverInfo

+ ".<br><br>It looks like you are using:<br>" + userAgent;

● Click again on “Send to Server” button

o The RPC callback will be called

o In this example a page reload is not needed

Page 49: RelProxy, Easy Class Reload and Scripting with Java

How JProxy can help you in

development time, a GWT example

Page 50: RelProxy, Easy Class Reload and Scripting with Java

A shell scripting

language named Java

Page 51: RelProxy, Easy Class Reload and Scripting with Java

A shell scripting lang named Java

● Your JDK includes a built-in API for compiling Java fileso Since Java 1.6

o The compiler API used by web app servers to compile servlets and

JSPs when changed (previously generated as servlet)

● RelProxy includes a script named jproxysh to execute

Java from source codeo Supported Windows and Unixes

● To execute code like this: (file example_java_shell)

#!/usr/bin/env jproxysh

String msg = args[0] + args[1];

System.out.println(msg);

System.out.println("example_java_shell 1 ");

example.javashellex.JProxyShellExample.exec();

Page 52: RelProxy, Easy Class Reload and Scripting with Java

A shell scripting lang named Java

● Obviously Java code is the code in main method

● jproxysh must be in PATH

● JAVA_HOME and CLASSPATH standard environment

variables must be definedo CLASSPATH must include relproxy-X.Y.jar

● This is the expected hierarchy in this example<root_folder>

example_java_shell (file)

example (folder)

javashellex (folder)

JProxyShellExample.java (file)

Page 53: RelProxy, Easy Class Reload and Scripting with Java

A shell scripting lang named Java

● Configuration options are defined by using environment

variables

● Example:

export JAVA_OPTS="-client -Xmx100m"

export JPROXYSH_CACHE_CLASS_FOLDER="/tmp/java_shell_test_classes"

export JPROXYSH_COMPILATION_OPTIONS="-source 1.6 -target 1.6"

./example_java_shell "HELLO " "WORLD!"

Not really needed (just an ex.)

To avoid recompiling (optional)

Page 54: RelProxy, Easy Class Reload and Scripting with Java

A shell scripting lang named Java

● Nothings prevents of executing a complete root classo File example_java_shell_complete_class

#!/usr/bin/env jproxysh

import example.javashellex.JProxyShellExample;

public class example_java_shell_complete_class {

public static void main(String[] args) {

String msg = args[0] + args[1];

System.out.println(msg);

System.out.println("example_java_shell_complete_class 1 ");

JProxyShellExample.exec();

}

}

Page 55: RelProxy, Easy Class Reload and Scripting with Java

A shell scripting lang named Java

● Of course a conventional root class is valido Yes you can execute a conventional Java program from source code!!

jproxysh $PROJECT/code/example_normal_class.java "HELLO " "WORLD!"

● Or just a code snippet

jproxysh -c 'System.out.print("This code snippet says: ");' \

'System.out.println("Hello World!!");'

● Or just start an interactive shell

jproxysh

Page 56: RelProxy, Easy Class Reload and Scripting with Java

JSR-223

Java Scripting API

Page 57: RelProxy, Easy Class Reload and Scripting with Java

JSR-223 Java Scripting API

● Yes RelProxy provides an implementation of JSR-223

API for a scripting language named “Java” or “FuckYou”JProxyConfig jpConfig = ...;

JProxyScriptEngineFactory factory = JProxyScriptEngineFactory.create();

ScriptEngineManager manager = new ScriptEngineManager();

manager.registerEngineName("Java", factory);

manager.getBindings().put("msg","HELLO GLOBAL WORLD!");

ScriptEngine engine = manager.getEngineByName("Java");

((JProxyScriptEngine)engine).init(jpConfig);

try

{

Bindings bindings = engine.createBindings();

bindings.put("msg","HELLO ENGINE SCOPE WORLD!");

StringBuilder code = new StringBuilder();

JProxyScriptEngine

has the same API as JProxy + eval(...)

Page 58: RelProxy, Easy Class Reload and Scripting with Java

JSR-223 Java Scripting API

code.append( " javax.script.Bindings bindings = context.getBindings(javax.script.ScriptContext.ENGINE_SCOPE); \n");

code.append( " String msg = (String)bindings.get(\"msg\"); \n");

code.append( " System.out.println(msg); \n");

code.append( " bindings = context.getBindings(javax.script.ScriptContext.GLOBAL_SCOPE); \n");

code.append( " msg = (String)bindings.get(\"msg\"); \n");

code.append( " System.out.println(msg); \n");

code.append( " example.javashellex.JProxyShellExample.exec(engine); \n");

code.append( " return \"SUCCESS\";");

String result = (String)engine.eval( code.toString() , bindings);

System.out.println(result);

}

catch(ScriptException ex) { ex.printStackTrace(); }

finally

{

((JProxyScriptEngine)engine).stop(); // Necessary if scanPeriod > 0 was defined

}

Page 59: RelProxy, Easy Class Reload and Scripting with Java

The Groovy Reload

Proxy

Page 60: RelProxy, Easy Class Reload and Scripting with Java

Err...

Another day...

Page 61: RelProxy, Easy Class Reload and Scripting with Java

THANKS &

ENJOY !!https://github.com/jmarranz/relproxy/

https://github.com/jmarranz/relproxy_examples/

Page 62: RelProxy, Easy Class Reload and Scripting with Java

Q & A

I’m sorry, half the world uses this stolen image from…(?)