diff --git a/.circleci/config.yml b/.circleci/config.yml
new file mode 100644
index 0000000..72bdef3
--- /dev/null
+++ b/.circleci/config.yml
@@ -0,0 +1,53 @@
+jobs:
+ build:
+ docker:
+ - image: sillelien/circleci-dollar-build-image
+
+ environment:
+ MAJOR_VERSION: 0.9
+ NEXT_MAJOR_VERSION: 0.10
+
+ MAVEN_OPTS: "-Xmx1g -DbuildNumber=${CIRCLE_BUILD_NUM}"
+ TZ: "/usr/share/zoneinfo/Europe/London"
+
+ working_directory: ~/java-as-script
+
+ branches:
+ ignore:
+ - gh-pages
+
+ steps:
+
+ - checkout
+
+ - restore_cache:
+ key: dependency-cache
+
+ - run:
+ name: init
+ command: /home/circleci/.build-init.sh
+
+ - run:
+ name: dependencies
+ command: |
+ ~/build-utils/maven_make_deps.sh
+
+ - save_cache:
+ key: dependency-cache
+ paths:
+ - ~/.gnupg
+ - ~/.m2
+ - run:
+ name: test
+ command: |
+ mvn -q -T 1C -Drat.skip -Dsource.skip=true -DgenerateReports=false -Dmaven.javadoc.skip=true integration-test
+ no_output_timeout: 600
+
+ - deploy:
+ command: |
+ if [ "${CIRCLE_BRANCH}" == "staging" ]; then
+ ~/build-utils/promote_from_staging.sh
+ fi
+ if [ "${CIRCLE_BRANCH}" == "master" ]; then
+ ~/build-utils/maven_deploy.sh
+ fi
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..986d0b0
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,11 @@
+[*]
+charset=utf-8
+end_of_line=lf
+insert_final_newline=true
+indent_style=space
+indent_size=4
+
+[{*.yml,*.yaml}]
+indent_style=space
+indent_size=2
+
diff --git a/.gitignore b/.gitignore
index c245488..7aa3ccc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,6 @@
/relproxy_dist_tmp/
/build/
+/tmp/
+.idea/workspace.xml
+out/
+target/
diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
new file mode 100644
index 0000000..e2957a4
--- /dev/null
+++ b/.idea/codeStyleSettings.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..2edacd3
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..97626ba
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/hotswap_agent.xml b/.idea/hotswap_agent.xml
new file mode 100644
index 0000000..8a869d9
--- /dev/null
+++ b/.idea/hotswap_agent.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..0a5158f
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/ItsNat_1_3_1.xml b/.idea/libraries/ItsNat_1_3_1.xml
new file mode 100644
index 0000000..06d4963
--- /dev/null
+++ b/.idea/libraries/ItsNat_1_3_1.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Maven__junit_junit_4_12.xml b/.idea/libraries/Maven__junit_junit_4_12.xml
new file mode 100644
index 0000000..d411041
--- /dev/null
+++ b/.idea/libraries/Maven__junit_junit_4_12.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml
new file mode 100644
index 0000000..f58bbc1
--- /dev/null
+++ b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_jetbrains_annotations_15_0.xml b/.idea/libraries/Maven__org_jetbrains_annotations_15_0.xml
new file mode 100644
index 0000000..f7a5c64
--- /dev/null
+++ b/.idea/libraries/Maven__org_jetbrains_annotations_15_0.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/annotations.xml b/.idea/libraries/annotations.xml
new file mode 100644
index 0000000..03e4ad1
--- /dev/null
+++ b/.idea/libraries/annotations.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/maven_ant_tasks_2_1_3.xml b/.idea/libraries/maven_ant_tasks_2_1_3.xml
new file mode 100644
index 0000000..c5e5cdf
--- /dev/null
+++ b/.idea/libraries/maven_ant_tasks_2_1_3.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..a6a1320
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1.8
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..c13ca56
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.mvn/extensions.xml b/.mvn/extensions.xml
new file mode 100644
index 0000000..6001478
--- /dev/null
+++ b/.mvn/extensions.xml
@@ -0,0 +1,8 @@
+
+
+ org.springframework.build
+ aws-maven
+ 5.0.0.RELEASE
+
+
diff --git a/.release b/.release
new file mode 100644
index 0000000..bf69677
--- /dev/null
+++ b/.release
@@ -0,0 +1 @@
+0.9.167
diff --git a/.release.details b/.release.details
new file mode 100644
index 0000000..a690306
--- /dev/null
+++ b/.release.details
@@ -0,0 +1 @@
+0.9.167 167 dbe48a61c158379efb5aab38f18ddc2b8a5f9e27 good-equerry-from-coalburns
diff --git a/relproxy/LICENSE-2.0.txt b/LICENSE
similarity index 100%
rename from relproxy/LICENSE-2.0.txt
rename to LICENSE
diff --git a/README.md b/README.md
index 07a9119..0e8c646 100644
--- a/README.md
+++ b/README.md
@@ -1,129 +1,106 @@
-RelProxy
-========
-RelProxy is a simple Java and Groovy hot class reloader for Java and Groovy providing transparent compilation and class reload on the fly, and scripting support and shell of pure Java code.
+Build: [](https://circleci.com/gh/sillelien/java-as-script)
-News
-------
+[  ](https://bintray.com/sillelien/maven/java-as-script/_latestVersion)
-- 2016-3-16 v0.8.8 Released. Support of static final fields in reloadable proxies. [Release Notes](https://github.com/jmarranz/relproxy/blob/master/relproxy/CHANGES.txt)
-- 2015-10-6 DZone article: [Improve Productivity With RelProxy for Java](https://dzone.com/articles/embedding-relproxy-in-your-java-framework-to-provi). About embedding RelProxy in your own Java framework.
-- 2015-10-1 v0.8.7 Released. Some improvement needed when embedding RelProxy Java using the scripting API. [Release Notes](https://github.com/jmarranz/relproxy/blob/master/relproxy/CHANGES.txt)
-- 2015-6-12 v0.8.6 Released. Support of class reloading of inner classes including anonymous. [Release Notes](https://github.com/jmarranz/relproxy/blob/master/relproxy/CHANGES.txt)
-- 2015-6-12 v0.8.5 Released. Improved performance when checking source changes and no change is detected. [Release Notes](https://github.com/jmarranz/relproxy/blob/master/relproxy/CHANGES.txt)
-- 2015-2-17 v0.8.4 Released. Added workaround to support Liferay (6.2 tested) [Release Notes](https://github.com/jmarranz/relproxy/blob/master/relproxy/CHANGES.txt).
- New [Liferay 6.2 example](https://github.com/jmarranz/relproxy_examples/tree/master/relproxy_ex_liferay-portlet) using RelProxy.
-- 2015-1-23 v0.8.3 Released. First release in JCenter and Maven Central [Release Notes](https://github.com/jmarranz/relproxy/blob/master/relproxy/CHANGES.txt)
-- 2015-2-5 [Java Hot Class Reloading with RelProxy in Development Mode, a GWT Example](http://java.dzone.com/articles/java-hot-class-reloading) JavaLobby article
-- 2015-1-30 [Slides](http://www.slideshare.net/jmarranz/relproxy-class-reload-and-easy-java-scripting) in English and [video](http://autentia.com/2015/01/30/relproxy-easy-class-reload-and-scripting-with-java-por-jose-maria-arranz/#) in Spanish of the RelProxy presentation in MadridJUG on January 28!
+Java-as-Script [](http://github.com/sillelien/java-as-script)
+==============
+Java-as-Script provides a hot reloading JSR-223 implementation for Java. This version is a fork of [the original project](https://github.com/jmarranz/relproxy) specifically it has been reduced in scope to focus entirely on the JSR-223 aspect of the original project. It is also primarily been forked for use in the [Dollar project](https://github.com/sillelien/dollar).
+Make sure you have the JCenter repo in your pom.xml
-Download Binaries and Docs
-------
-
-[Download](https://sourceforge.net/projects/relproxy/files/)
-
-Distribution file includes binaries, examples, manual and javadocs.
-
-Artefacts are uploaded to [JCenter](https://bintray.com/jmarranz/maven/relproxy/view) ([direct](https://jcenter.bintray.com/com/innowhere/relproxy/)) and [Maven Central](http://mvnrepository.com/artifact/com.innowhere/relproxy) ([direct](https://oss.sonatype.org/content/repositories/releases/com/innowhere/relproxy/)) repositories
-
-Maven:
+```xml
+
+
+
+ false
+
+ central
+ bintray
+ http://jcenter.bintray.com
+
+
+```
+
+ Then just add the following dependency
```xml
-com.innowhere
-relproxy
-(version)
-jar
+
+ com.sillelien
+ java-as-script
+ 0.9.135
+
```
-Overview
-------
-
-RelProxy is a simple Java and Groovy hot class reloader for Java and Groovy providing transparent compilation and class reload on the fly, and scripting support and shell of pure
-Java code.
-
-RelProxy is:
-
-1) A simple Java and Groovy hot class reloader for Java and Groovy providing transparent compilation and class reload on the fly with no need of a bootstrap class loader agent and
-avoiding context reloading. Reloading happens only in memory. Class reloading can be used in development phase and optionally in production (if source code can be uploaded to
-production).
-
-2) A scripting environment to execute Java code snippets the same as a shell script. There is no new language, is Java compiled on the fly, code in the initial archive can call
-to other normal Java files. Optionally .class can be saved in a cache to provide the fastest "scripting" language of the world.
-
-3) Execution of Java code snippets in command line (no need of packaging into an archive).
-
-4) A simple shell to code, edit and execute code snippets in Java interactively.
-
-5) JSR 223 Scripting API implementation for "Java" as the target scripting language. You can embed and execute Java code as scripting into your Java program.
+[  ](https://bintray.com/sillelien/maven/java-as-script/_latestVersion)
+Below is a complete example of using Java-as-Script as a JSR-223 scripting engine, with the language being Java.
+```java
+package com.sillelien.jas;
-In case of Java "scripting", there is no a new language, is pure Java code with compilation on the fly.
+import com.sillelien.jas.jproxy.JProxy;
+import com.sillelien.jas.jproxy.JProxyConfig;
+import com.sillelien.jas.jproxy.JProxyScriptEngine;
+import com.sillelien.jas.jproxy.JProxyScriptEngineFactory;
-In spite of RelProxy is a general purpose tool it was conceived for [ItsNat web framework](http://www.itsnat.org) to provide hot class reload in development time...
-and if you want also in production. RelProxy is standalone and has no dependency on ItsNat.
+import javax.script.Bindings;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+import java.util.Collections;
+import java.util.List;
-RelProxy Manual explains how to configure and use RelProxy in NetBeans and Eclipse avoiding class reloading (of course other IDEs are possible).
+public class Demo {
-There are several examples of how to use RelProxy with most popular Java web frameworks ready to run into [RelProxy Examples](https://github.com/jmarranz/relproxy_examples)
-repository. Also [ItsNat Experiments](https://github.com/jmarranz/itsnat/tree/master/inexperiments) includes an ItsNat example using NetBeans with Ant, to reload Java and Groovy code.
-The most complex example is [relproxy_test_itsnat](https://github.com/jmarranz/relproxy/tree/master/relproxy_test_itsnat) created for internal testing.
+ public static void main(String[] ignored) throws Exception {
-Besides fast and custom Java (and Groovy) class reloading, RelProxy provides a Java shell scripting environment to execute:
+ //Initializing and configuring the JSR-223 script engine
+ JProxyConfig jpConfig = JProxy.createJProxyConfig();
+ jpConfig.setEnabled(true)
+ .setRelProxyOnReloadListener((objOld, objNew, proxy, method, args) -> {
+ //TODO
+ })
+ // .setInputPath(".")
+ .setScanPeriod(-1)
+ .setClassFolder("./tmp/classes")
+ .setCompilationOptions(Collections.emptyList())
+ .setJProxyDiagnosticsListener(diagnostics -> {
+ List> diagnosticList = diagnostics.getDiagnostics();
+ diagnosticList.stream()
+ .filter(diagnostic -> diagnostic.getKind().equals(Diagnostic.Kind.ERROR))
+ .forEach(System.err::println);
+ });
-1) A pure Java archive packaged like a shell script file with no need of previous compilation, compilation is done on the fly and optionally .class can be saved in a
-cache to provide the fastest "scripting" language of the world. Code in the initial archive can call to other normal Java files, again with compilation on the fly
-and optional compilation caching as .class files. [Example 1](https://github.com/jmarranz/relproxy/blob/master/relproxy/src/test/resources/example_java_shell)
-and [example 2](https://github.com/jmarranz/relproxy/blob/master/relproxy/src/test/resources/example_java_shell_complete_class) or just
-a conventional [Java source file](https://github.com/jmarranz/relproxy/blob/master/relproxy/src/test/resources/example_normal_class.java) (yes you can execute a conventional
-JavaSE application from source code).
+ JProxyScriptEngineFactory factory = JProxyScriptEngineFactory.create();
-2) Execution of Java code snippets in command line (no need of packaging in an archive). [Example](https://github.com/jmarranz/relproxy/blob/master/relproxy/test_cmd/test_java_shell_snippet_launcher.sh).
+ ScriptEngineManager manager = new ScriptEngineManager();
+ manager.registerEngineName("java", factory);
+ Bindings bindings = manager.getBindings();
+ bindings.put("in", "World");
-3) Interactive console to edit and execute Java code (ever compilation on the fly). [Example of launcher](https://github.com/jmarranz/relproxy/blob/master/relproxy/test_cmd/test_java_shell_interactive_launcher.sh)
+ ScriptEngine engine = manager.getEngineByName("java");
+ JProxyScriptEngine scriptEngine = (JProxyScriptEngine) engine;
+ scriptEngine.init(jpConfig);
-Finally RelProxy implements the official JSR-223 [Java Scripting API](http://docs.oracle.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.html) as found in Java 1.6 for "Java" language.
-By using this API you can embed Java as any other scripting language in your Java code.
+ //Your code goes here, e.g.
-Yes, Java is also a dynamic scripting language with no need of manual compilation, and it is extremely fast and robust.
+ scriptEngine.eval("System.out.println(\"Hello \"+context.getAttribute(\"in\",javax.script.ScriptContext.ENGINE_SCOPE));return null;\n",bindings);
-Online Docs Last Version
-------
+ }
+}
-[Manual](http://relproxy.sourceforge.net/docs/manual/manual.html)
-
-[JavaDocs](http://relproxy.sourceforge.net/docs/javadoc/)
-
-Examples
-------
-
-See the GitHub repository [RelProxy Examples](https://github.com/jmarranz/relproxy_examples)
-
-Questions and discussions
-------
-
-There is a [Google Group](https://groups.google.com/forum/#!forum/relproxy) for RelProxy.
-
-Bug Reporting
-------
-
-Use this GitHub project.
-
-
-Articles/Blogs/Presentations
-------
-
-- Oct 6,2015 [Improve Productivity With RelProxy for Java](https://dzone.com/articles/embedding-relproxy-in-your-java-framework-to-provi). About embedding RelProxy in your own Java framework.
-
-- Feb 19,2015 [No longer virgin, uploaded my first jar to Maven Central, and it was not nice](http://jmarranz.blogspot.com.es/2015/02/no-longer-virgin-uploaded-my-first-jar.html). [JavaLobby](http://java.dzone.com/articles/no-longer-virgin-uploaded-my). [Bintray Quote](http://blog.bintray.com/2015/02/19/another-one-bites-the-maven-central-dust-and-saved-by-bintray/).
+```
-- Feb 5,2015 [Java Hot Class Reloading with RelProxy in Development Mode, a GWT Example](http://java.dzone.com/articles/java-hot-class-reloading)
+Dependencies: [](https://www.versioneye.com/user/projects/5960064c6725bd0049735d0b)
-- Jan 28,2015 [Slides](http://www.slideshare.net/jmarranz/relproxy-class-reload-and-easy-java-scripting) in English and [video](http://autentia.com/2015/01/30/relproxy-easy-class-reload-and-scripting-with-java-por-jose-maria-arranz/#) ([youtube](https://www.youtube.com/watch?v=dyUhX6t5t-Y)) in Spanish of the RelProxy presentation in MadridJUG
+-------
-- Dec 31,2014 [RelProxy v0.8.1 reduce el numero de redeploys en GWT-RPC y otros Java web frameworks](http://www.javahispano.org/portada/2014/12/31/relproxy-v081-reduce-el-numero-de-redeploys-en-gwt-rpc-y-otr.html) Published at javaHispano
+** If you use this project please consider giving us a star on [GitHub](http://github.com/sillelien/java-as-script). **
-- Feb 15,2014 [v0.8 announce at JavaLobby](http://java.dzone.com/articles/presenting-relproxy-hot-class)
+Please contact me through Gitter (chat) or through GitHub Issues.
-- Feb 12,2014 [v0.8 announce at javaHispano](http://www.javahispano.org/portada/2014/2/12/publicado-relproxy-v08-hot-class-reloader-y-scripting-para-j.html)
+[](https://github.com/sillelien/java-as-script/issues) [](https://gitter.im/sillelien/java-as-script?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+For commercial support please contact me directly.
+-------
diff --git a/README.staged.md b/README.staged.md
new file mode 100644
index 0000000..cbc0d85
--- /dev/null
+++ b/README.staged.md
@@ -0,0 +1,106 @@
+Build: [](https://circleci.com/gh/sillelien/java-as-script)
+
+[  ](https://bintray.com/sillelien/maven/java-as-script/_latestVersion)
+
+Java-as-Script [](http://github.com/sillelien/java-as-script)
+==============
+Java-as-Script provides a hot reloading JSR-223 implementation for Java. This version is a fork of [the original project](https://github.com/jmarranz/relproxy) specifically it has been reduced in scope to focus entirely on the JSR-223 aspect of the original project. It is also primarily been forked for use in the [Dollar project](https://github.com/sillelien/dollar).
+
+Make sure you have the JCenter repo in your pom.xml
+
+```xml
+
+
+
+ false
+
+ central
+ bintray
+ http://jcenter.bintray.com
+
+
+```
+
+ Then just add the following dependency
+
+```xml
+
+ com.sillelien
+ java-as-script
+ 0.9.142
+
+```
+
+[  ](https://bintray.com/sillelien/maven/java-as-script/_latestVersion)
+
+Below is a complete example of using Java-as-Script as a JSR-223 scripting engine, with the language being Java.
+
+```java
+package com.sillelien.jas;
+
+import com.sillelien.jas.jproxy.JProxy;
+import com.sillelien.jas.jproxy.JProxyConfig;
+import com.sillelien.jas.jproxy.JProxyScriptEngine;
+import com.sillelien.jas.jproxy.JProxyScriptEngineFactory;
+
+import javax.script.Bindings;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+import java.util.Collections;
+import java.util.List;
+
+public class Demo {
+
+ public static void main(String[] ignored) throws Exception {
+
+ //Initializing and configuring the JSR-223 script engine
+ JProxyConfig jpConfig = JProxy.createJProxyConfig();
+ jpConfig.setEnabled(true)
+ .setRelProxyOnReloadListener((objOld, objNew, proxy, method, args) -> {
+ //TODO
+ })
+ // .setInputPath(".")
+ .setScanPeriod(-1)
+ .setClassFolder("./tmp/classes")
+ .setCompilationOptions(Collections.emptyList())
+ .setJProxyDiagnosticsListener(diagnostics -> {
+ List> diagnosticList = diagnostics.getDiagnostics();
+ diagnosticList.stream()
+ .filter(diagnostic -> diagnostic.getKind().equals(Diagnostic.Kind.ERROR))
+ .forEach(System.err::println);
+ });
+
+ JProxyScriptEngineFactory factory = JProxyScriptEngineFactory.create();
+
+ ScriptEngineManager manager = new ScriptEngineManager();
+ manager.registerEngineName("java", factory);
+ Bindings bindings = manager.getBindings();
+ bindings.put("in", "World");
+
+ ScriptEngine engine = manager.getEngineByName("java");
+ JProxyScriptEngine scriptEngine = (JProxyScriptEngine) engine;
+ scriptEngine.init(jpConfig);
+
+ //Your code goes here, e.g.
+
+ scriptEngine.eval("System.out.println(\"Hello \"+context.getAttribute(\"in\",javax.script.ScriptContext.ENGINE_SCOPE));return null;\n",bindings);
+
+ }
+}
+
+```
+
+Dependencies: [](https://www.versioneye.com/user/projects/5960064c6725bd0049735d0b)
+
+-------
+
+** If you use this project please consider giving us a star on [GitHub](http://github.com/sillelien/java-as-script). **
+
+Please contact me through Gitter (chat) or through GitHub Issues.
+
+[](https://github.com/sillelien/java-as-script/issues) [](https://gitter.im/sillelien/java-as-script?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
+For commercial support please contact me directly.
+-------
diff --git a/annotations/java/io/annotations.xml b/annotations/java/io/annotations.xml
new file mode 100644
index 0000000..e658d6e
--- /dev/null
+++ b/annotations/java/io/annotations.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/annotations/java/lang/annotations.xml b/annotations/java/lang/annotations.xml
new file mode 100644
index 0000000..28cc73d
--- /dev/null
+++ b/annotations/java/lang/annotations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/annotations/java/lang/reflect/annotations.xml b/annotations/java/lang/reflect/annotations.xml
new file mode 100644
index 0000000..7aae6df
--- /dev/null
+++ b/annotations/java/lang/reflect/annotations.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/annotations/java/net/annotations.xml b/annotations/java/net/annotations.xml
new file mode 100644
index 0000000..669663a
--- /dev/null
+++ b/annotations/java/net/annotations.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/annotations/java/util/annotations.xml b/annotations/java/util/annotations.xml
new file mode 100644
index 0000000..4df6ebd
--- /dev/null
+++ b/annotations/java/util/annotations.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/annotations/java/util/jar/annotations.xml b/annotations/java/util/jar/annotations.xml
new file mode 100644
index 0000000..e9bba3d
--- /dev/null
+++ b/annotations/java/util/jar/annotations.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/annotations/javax/script/annotations.xml b/annotations/javax/script/annotations.xml
new file mode 100644
index 0000000..786bc4d
--- /dev/null
+++ b/annotations/javax/script/annotations.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/annotations/javax/tools/annotations.xml b/annotations/javax/tools/annotations.xml
new file mode 100644
index 0000000..0f5f810
--- /dev/null
+++ b/annotations/javax/tools/annotations.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java-as-script.iml b/java-as-script.iml
new file mode 100644
index 0000000..860b236
--- /dev/null
+++ b/java-as-script.iml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..0f504ca
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,575 @@
+
+
+ 4.0.0
+
+ com.sillelien
+ java-as-script
+ 0
+
+ Java-as-Script
+
+ Simple Java and Groovy hot class reloader,and Java based shell and scripting used by Dollar project,
+ original project is https://github.com/jmarranz/relproxy
+
+
+
+
+ 2.0.2
+ 1.8
+ 3.3.9
+
+
+
+ ${maven.version}
+
+
+
+ https://github.com/sillelien/java-as-script
+
+
+ The Apache License, Version 2.0
+ http://www.apache.org/licenses/LICENSE-2.0.txt
+
+
+
+
+ Jose Maria Arranz
+ jmarranz@innowhere.com
+ Innowhere Software
+ http://www.innowhere.com
+
+ Original Author
+
+
+
+
+
+
+ Daniel López (greeneyed)
+
+
+ https://github.com/Verdoso
+
+ Original Contributor
+
+
+
+ Michael Vorburger
+ mike@vorburger.ch
+ Vorburger.CH
+ http://www.vorburger.ch
+
+ Original Contributor
+
+
+
+
+
+ scm:git:git@github.com:sillelien/dollar-java-as-script.git
+ scm:git:git@github.com:sillelien/dollar-java-as-script.git
+ git@github.com:sillelien/dollar-java-as-script.git
+
+
+
+
+
+
+
+ org.jetbrains
+ annotations
+ 15.0
+
+
+ org.slf4j
+ slf4j-api
+ 1.7.22
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+
+
+
+
+
+
+ org.apache.rat
+ apache-rat-plugin
+ 0.12
+
+ true
+ true
+
+ src/test/**
+ src/main/webapp/**
+ dist/**
+ dist-skel/**
+ **/*.markdown
+ **/*.ds
+ **/*.md
+ **/*.sh
+ **/*.yml
+ **/*.iml
+ **/*.html
+ key.txt
+
+
+
+
+ org.codehaus.mojo
+ findbugs-maven-plugin
+ 3.0.4
+
+ Default
+ High
+ true
+
+ target/site
+
+
+
+ org.apache.maven.plugins
+ maven-project-info-reports-plugin
+ 2.9
+
+
+ com.google.code.findbugs
+ bcel
+ ${bcel.version}
+
+
+ org.apache.maven.shared
+ maven-shared-jar
+ 1.2
+
+
+ org.apache.bcel
+ bcel
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-site-plugin
+ 3.6
+
+
+ attach-descriptor
+
+ attach-descriptor
+
+
+
+
+ en
+
+
+
+ org.apache.maven.doxia
+ doxia-module-markdown
+ 1.7
+
+
+ org.apache.maven.skins
+ maven-fluido-skin
+ 1.6
+
+
+
+
+ com.versioneye
+ versioneye-maven-plugin
+ 3.11.4
+
+ 0c797be864338a3649f0
+ sillelien
+ Owners
+
+
+
+ org.complykit
+ license-check-maven-plugin
+ 0.5.3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ agpl-3.0
+
+ gpl-2.0
+
+ gpl-3.0
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-clean-plugin
+ 3.0.0
+
+
+ org.apache.maven.plugins
+ maven-install-plugin
+ 2.5.2
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ 3.0.2
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ 2.8.2
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.0.2
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ 1.4.1
+
+
+ enforce-versions
+
+ enforce
+
+
+
+
+
+
+
+
+ [${maven.version},]
+
+
+ ${jdk.version}
+
+
+ unix
+
+
+ Best Practice is to always define plugin versions!
+ true
+ true
+ true
+ clean,deploy,site
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.6.1
+
+ ${jdk.version}
+ ${jdk.version}
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.20
+
+
+
+
+ **/*Test.java
+
+ 4
+ true
+ -Xmx256m
+ methods
+ 32
+
+
+
+ org.apache.maven.surefire
+ surefire-junit47
+ 2.20
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.10.4
+
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+
+
+ maven-scm-plugin
+ 1.9.5
+
+ ${project.artifactId}-${project.version}
+
+
+
+ org.pitest
+ pitest-maven
+ 1.2.2
+
+
+ com.sillelien.*
+
+
+ com.sillelien.*
+
+ 0
+ 0
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.0.1
+
+
+ attach-sources
+
+ jar
+
+
+
+
+
+
+
+
+
+ com.versioneye
+ versioneye-maven-plugin
+
+
+ org.complykit
+ license-check-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-clean-plugin
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ org.apache.maven.plugins
+ maven-install-plugin
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+
+
+ org.apache.maven.plugins
+ maven-site-plugin
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ versions-maven-plugin
+ 2.4
+
+
+
+ maven-scm-plugin
+
+
+ org.codehaus.mojo
+ findbugs-maven-plugin
+
+
+ org.pitest
+ pitest-maven
+
+
+ org.apache.rat
+ apache-rat-plugin
+
+
+ verify
+
+ check
+
+
+
+
+
+ org.pitest
+ pitest-maven
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
+
+
+
+ org.springframework.build
+ aws-maven
+ 5.0.0.RELEASE
+
+
+
+
+
+
+
+ s3
+
+ true
+
+ s3
+
+
+
+
+ dollar-s3-release-repo
+ Release Repository for Dollar
+ s3://dollar-repo/release
+
+
+ dollar-s3-snapshot-repo
+ Snapshot Repository for Dollar
+ s3://dollar-repo/snapshot
+
+
+
+
+
+
+
+ dollar-s3-release-repo
+ S3 Release Repository for component1
+ s3://dollar-repo/release
+
+ true
+
+
+ false
+
+
+
+ dollar-s3-snapshot-repo
+ Component1-s3-snapshot-repo
+ s3://dollar-repo/snapshot
+
+ false
+
+
+ true
+
+
+
+
+
+
+
+ bintray
+
+
+ http://sillelien.github.io/${project.artifactId}
+ scm:git:git@github.com:sillelien/${project.artifactId}.git
+
+
+ bintray-sillelien-maven
+ sillelien-maven
+ https://api.bintray.com/maven/sillelien/maven/${project.artifactId}/;publish=1
+
+
+
+
+
+
+
+ false
+
+ bintray-sillelien-maven
+ bintray
+ http://dl.bintray.com/sillelien/maven
+
+
+
+
+
+
+
+
diff --git a/relproxy/.gitignore b/relproxy/.gitignore
deleted file mode 100644
index f394c0e..0000000
--- a/relproxy/.gitignore
+++ /dev/null
@@ -1,10 +0,0 @@
-/target/
-/build
-/docs_internal
-/tmp
-.classpath
-.project
-.settings/
-# .gradle/
-
-conf/conf_local.properties
diff --git a/relproxy/CHANGES.txt b/relproxy/CHANGES.txt
deleted file mode 100644
index b6399a4..0000000
--- a/relproxy/CHANGES.txt
+++ /dev/null
@@ -1,66 +0,0 @@
-
-RELEASE CHANGES
-
-* 0.8.8
-
- - Support of static final fields in reloadable proxies.
-
-* 0.8.7
-
- - Some improvement needed when embedding RelProxy Java using the scripting API (avoiding one unnecessary first class reload).
- - Added chapter to Manual: "Embedding RelProxy Java in your Java framework to provide hot reload".
- - Added new example in RelProxy Examples repository named relproxy_builtin_ex on how to embed RelProxy.
-
-* 0.8.6
-
- - Support of class reloading in inner classes including anonymous inner classes. Chapter "JProxy or how to be able..." updated accordingly. This feature
- is used by ItsNat 1.4, this release uses RelProxy internally for user class reloading (mainly listeners).
-
-* 0.8.5
-
- - Improved performance reducing blocking code when checking source code changes and no change is detected.
-
-* 0.8.4
-
- - Added the method JProxyConfig.setRequiredExtraJarPaths(String[] inputJarPaths) to workaround a problem with Liferay 6.2.
- - Added JProxy.create(Object,Class>[]), GProxy.create(Object,Class>[]),JProxyScriptEngine.create(Object,Class>[]) for classes implementing multiple interfaces
- - The call proxy.equals(proxy2) returns true if both proxies have associated the same original object and there is no reload.
- - Added to Manual "Solving jar manifest configuration problems in JProxy" and "Identity of returned proxies"
-
-* 0.8.3
-
- - First release published on bintray.com/JCenter and Maven Central. In Maven just add to your POM:
-
-
- com.innowhere
- relproxy
- 0.8.3
-
-
-* 0.8.2
-
- - Optimization: method JProxyInputSourceFileExcludedListener.isExcluded(File file,File) is called being parameter file also a directory, if the directory is fully
- excluded, RelProxy doesn't call isExcluded for files into the folder. Useful for big source code bases and used RelProxy for normal source code folders.
- - Reload reloadable classes using a new ClassLoader is done only when a exposed method of a singleton registered on JProxy is called.
- - Added JProxy.isEnabled()
- - API for configuration of JProxyScriptEngineFactory and JProxyScriptEngine has changed.
- - JProxyScriptEngine has now the same methods (and same behavior) as JProxy.
- - Removed JPROXYSH_SCAN_PERIOD, has no sense in shell scripting.
- - Bug fix in case of paths with spaces in JProxy.
- - Bug fix in case of ".." in paths in JProxy.
- - Manual has been very improved documenting new features and new chapters.
- - A lot of examples of using RelProxy with popular Java web frameworks.
-
-* 0.8.1
-
- - Fixed a problem with class localization and loading of javax.* classes not included in Java core (ex javax.servlet classes)
- - Support of multiple input folder roots for sources: JProxyConfig.setInputPaths(String[] inputPaths)
- - Added listener JProxyConfig.setRelProxyOnReloadListener(RelProxyOnReloadListener) to expecify excluded files
- - Added listener JProxyConfig.setJProxyCompilerListener(JProxyCompilerListener) to monitor when files are compiled
- - Added JProxyConfig.isRunning() to detect whether JProxy is configured and running
- - Added new chapters to manual:
- "Setting up a web project based on a Maven POM in NetBeans to use JProxy or GProxy"
- "How JProxy can help you only in development time (GWT example)"
-
-* 0.8 First release
-
diff --git a/relproxy/ant/maven-ant-tasks-2.1.3.jar b/relproxy/ant/maven-ant-tasks-2.1.3.jar
deleted file mode 100644
index bec446f..0000000
Binary files a/relproxy/ant/maven-ant-tasks-2.1.3.jar and /dev/null differ
diff --git a/relproxy/bin/jproxysh b/relproxy/bin/jproxysh
deleted file mode 100644
index c9863b0..0000000
--- a/relproxy/bin/jproxysh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-
-if [ ! -z "$JPROXYSH_CACHE_CLASS_FOLDER" ]; then JPROXYSH_CACHE_CLASS_FOLDER_PARAM=-DcacheClassFolder="$JPROXYSH_CACHE_CLASS_FOLDER"
-fi
-
-if [ ! -z "$JPROXYSH_COMPILATION_OPTIONS" ]; then JPROXYSH_COMPILATION_OPTIONS_PARAM=-DcompilationOptions="$JPROXYSH_COMPILATION_OPTIONS"
-fi
-
-
-"$JAVA_HOME/bin/java" $JAVA_OPTS com.innowhere.relproxy.jproxy.JProxyShell "$@" \
- "$JPROXYSH_CACHE_CLASS_FOLDER_PARAM" \
- "$JPROXYSH_COMPILATION_OPTIONS_PARAM"
diff --git a/relproxy/conf/conf.properties b/relproxy/conf/conf.properties
deleted file mode 100644
index 68f9fe3..0000000
--- a/relproxy/conf/conf.properties
+++ /dev/null
@@ -1,16 +0,0 @@
-
-program.name=RelProxy
-
-# CHANGE ALSO IN RelProxy.getVersion()
-program.version=0.8.8
-program.javadoc.prog.version=0.8.8
-program.javadoc.doc.version=1.0
-
-# El proyecto al ser Maven no Ant ${program} no est\u00e1 definido, lo definimos
-program = ${basedir}
-
-program.target=${program}/target
-
-program.src=${program}/src/main/java
-
-
diff --git a/relproxy/distribute.xml b/relproxy/distribute.xml
deleted file mode 100644
index afe6c42..0000000
--- a/relproxy/distribute.xml
+++ /dev/null
@@ -1,165 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/relproxy/pom.xml b/relproxy/pom.xml
deleted file mode 100644
index 369a555..0000000
--- a/relproxy/pom.xml
+++ /dev/null
@@ -1,158 +0,0 @@
-
-
- 4.0.0
- com.innowhere
- relproxy
- 0.8.8
- jar
-
- relproxy
- Simple Java and Groovy hot class reloader,and Java based shell and scripting.
- https://github.com/jmarranz/relproxy
-
-
- The Apache License, Version 2.0
- http://www.apache.org/licenses/LICENSE-2.0.txt
-
-
-
-
- Jose Maria Arranz
- jmarranz@innowhere.com
- Innowhere Software
- http://www.innowhere.com
-
-
-
-
-
- Daniel López (greeneyed)
-
-
- https://github.com/Verdoso
-
-
- Michael Vorburger
- mike@vorburger.ch
- Vorburger.CH
- http://www.vorburger.ch
-
-
-
-
- scm:git:git@github.com:jmarranz/relproxy.git
- scm:git:git@github.com:jmarranz/relproxy.git
- git@github.com:jmarranz/relproxy.git
-
-
-
-
- UTF-8
- 1.6
- 1.6
-
-
-
-
-
- junit
- junit
- 4.10
- test
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 2.0.2
-
- 1.6
- 1.6
- ${project.build.sourceEncoding}
-
-
-
-
- org.apache.maven.plugins
- maven-resources-plugin
- 2.4.3
-
- ${project.build.sourceEncoding}
-
-
-
-
- org.asciidoctor
- asciidoctor-maven-plugin
- 1.5.2
-
-
- output-html
- generate-resources
-
- process-asciidoc
-
-
- highlightjs
- html
-
-
-
-
-
-
-
-
- src/main/asciidoc/
-
- true
- images/
-
-
-
-
-
- org.apache.maven.plugins
- maven-source-plugin
- 2.4
-
-
- attach-sources
-
- jar
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
- 2.10.1
-
-
- attach-javadocs
-
- jar
-
-
-
-
- true
- true
- RelProxy v${project.version}
- RelProxy v${project.version}
-
- com.innowhere.relproxy.impl
-
-
-
-
-
-
-
-
diff --git a/relproxy/src/main/asciidoc/css/better_toc.css b/relproxy/src/main/asciidoc/css/better_toc.css
deleted file mode 100644
index 6f2c03f..0000000
--- a/relproxy/src/main/asciidoc/css/better_toc.css
+++ /dev/null
@@ -1,4 +0,0 @@
-/* Truco para añadir al menu lateral izdo una bolita a cada item */
-
-ul.sectlevel1 { list-style-type: square !important; }
-ul.sectlevel2 { list-style-type: circle !important; }
diff --git a/relproxy/src/main/asciidoc/images/browser_1.png b/relproxy/src/main/asciidoc/images/browser_1.png
deleted file mode 100644
index 710fdc6..0000000
Binary files a/relproxy/src/main/asciidoc/images/browser_1.png and /dev/null differ
diff --git a/relproxy/src/main/asciidoc/images/browser_2.png b/relproxy/src/main/asciidoc/images/browser_2.png
deleted file mode 100644
index 0348771..0000000
Binary files a/relproxy/src/main/asciidoc/images/browser_2.png and /dev/null differ
diff --git a/relproxy/src/main/asciidoc/images/browser_3.png b/relproxy/src/main/asciidoc/images/browser_3.png
deleted file mode 100644
index 6445bde..0000000
Binary files a/relproxy/src/main/asciidoc/images/browser_3.png and /dev/null differ
diff --git a/relproxy/src/main/asciidoc/images/edit_web_module.png b/relproxy/src/main/asciidoc/images/edit_web_module.png
deleted file mode 100644
index cbebc3b..0000000
Binary files a/relproxy/src/main/asciidoc/images/edit_web_module.png and /dev/null differ
diff --git a/relproxy/src/main/asciidoc/images/filesync_conf.png b/relproxy/src/main/asciidoc/images/filesync_conf.png
deleted file mode 100644
index 3a51c0d..0000000
Binary files a/relproxy/src/main/asciidoc/images/filesync_conf.png and /dev/null differ
diff --git a/relproxy/src/main/asciidoc/images/filesync_force_file_sync.png b/relproxy/src/main/asciidoc/images/filesync_force_file_sync.png
deleted file mode 100644
index 3ad13fd..0000000
Binary files a/relproxy/src/main/asciidoc/images/filesync_force_file_sync.png and /dev/null differ
diff --git a/relproxy/src/main/asciidoc/images/install_filesync1.png b/relproxy/src/main/asciidoc/images/install_filesync1.png
deleted file mode 100644
index ae93bb5..0000000
Binary files a/relproxy/src/main/asciidoc/images/install_filesync1.png and /dev/null differ
diff --git a/relproxy/src/main/asciidoc/images/module_conf.png b/relproxy/src/main/asciidoc/images/module_conf.png
deleted file mode 100644
index 0069523..0000000
Binary files a/relproxy/src/main/asciidoc/images/module_conf.png and /dev/null differ
diff --git a/relproxy/src/main/asciidoc/images/publishing.png b/relproxy/src/main/asciidoc/images/publishing.png
deleted file mode 100644
index 3571d76..0000000
Binary files a/relproxy/src/main/asciidoc/images/publishing.png and /dev/null differ
diff --git a/relproxy/src/main/asciidoc/images/server_options.png b/relproxy/src/main/asciidoc/images/server_options.png
deleted file mode 100644
index dd0fd0f..0000000
Binary files a/relproxy/src/main/asciidoc/images/server_options.png and /dev/null differ
diff --git a/relproxy/src/main/asciidoc/manual.asciidoc b/relproxy/src/main/asciidoc/manual.asciidoc
deleted file mode 100644
index 3552f6a..0000000
--- a/relproxy/src/main/asciidoc/manual.asciidoc
+++ /dev/null
@@ -1,2654 +0,0 @@
-// :icons: font es necesario para que se considere en la generación de HTML usando Font Awesome en donde palabras especiales son iconos por ej en "NOTE:" "IMPORTANT:" etc
-:icons: font
-// :linkcss: por defecto está definida por si acaso, para linkar asciidoctor.css
-:linkcss:
-// :copycss: es para que copie el asciidoctor.css por defecto junto al HTML generado
-:copycss:
-// :sectanchors: para mostrar un link de "posicionar" arriba cada título
-:sectanchors:
-:toc2:
-// usamos highlightjs o prettify porque coderay falla (aunque está incluido)
-// NOTA: se configura en el POM pues aquí parece que no funciona
-// :source-highlighter: highlightjs
-
-
-= RelProxy
-
-++++
-
-++++
-
-(C) Jose María Arranz Santamaría
-v0.8.8 March 16, 2016
-
-_Because Java is also a dynamic language and Groovy can still be a dynamic language in a Java based environment._
-
-== What is RelProxy
-
-RelProxy is:
-
-. A simple Java and Groovy hot class reloader for Java and Groovy providing transparent compilation and class reload on the fly with no need of a bootstrap class loader agent
-and avoiding context reloading. Reloading happens only in memory. Class reloading can be used in development phase and optionally in production (if source code can be uploaded
-to production).
-. A scripting environment to execute Java code snippets the same as a shell script. There is no new language, is Java compiled on the fly, code in the initial archive can call
-to other normal Java files. Optionally .class can be saved in a cache to provide *the fastest "scripting" language* of the world.
-. Execution of Java code snippets in command line (no need of packaging into an archive).
-. A simple shell to code, edit and execute code snippets in Java interactively.
-. JSR 223 Scripting API implementation for "Java" as the target scripting language. You can embed and execute Java code as scripting into your Java program.
-
-
-
-== The origins of RelProxy
-
-
-RelProxy was born as the result of the intent of providing a way to hot class reloading for the http://www.itsnat.org[ItsNat] Java web framework in development and optionally
-in production time.
-
-ItsNat templates are pure X/HTML/SVG files with no logic executed in server, when a template is changed ItsNat automatically reloads the file and the new version is used
-in the next attempt of using the template. View logic is coded in Java by using Java W3C DOM APIs modifying ItsNat templates and finally generating the required markup in load
-time or JavaScript code as the result of AJAX events.
-
-As said before, ItsNat provided hot reloading of markup templates, but view logic, coded in Java, remained too static, if you needed to change the view logic you needed to redeploy
-the web application, in the best case only the web application context is reloaded. Providing some hot class reloading of view logic (coded in Java or Groovy as we will see later) with no
-need of context reload (context reload can be quick or very slow depending of the size of the application and session can be lost) would dramatically increase
-the productivity of ItsNat in development and in an edge case, view logic changes would be possible in production.
-
-Redeploying is not strange to Java web developers when you leave the world of JSPs, JSPs were designed to be hot reloaded including logic coded in Java, server centric frameworks
-usually provides some kind of hot reloaded templating, but in most of them conventional Java code is not hot reloaded unless context reload or redeploy.
-
-The first attempt to provide hot reload of view logic to ItsNat was trying to use Groovy, many people think Groovy is an "interpreted" language and is not,
-Groovy is also a language compiled to bytecode, but compilation happens on demand, generated bytecode is usually more flexible ("dynamic") than conventional Java and hot class reloading is built-in.
-The problem of using Groovy in ItsNat was the need of registering Groovy listeners in ItsNat Java listeners (view processors), when registering
-on an ItsNat (Java) listener the object registered is "frozen" and cannot be reloaded...
-
-This was the context to invent RelProxy and is the reason of the name, Reload + Proxy, the first feature of RelProxy was creating Java proxies (`java.lang.reflect.Proxy`) to wrap Groovy objects before registering
-into Java methods (ItsNat listeners), RelProxy proxies ever use the last version of the Groovy class by using the hot class loader of Groovy, by this way we can hot class reload classes in ItsNat... coded in Groovy.
-
-The next step is obvious, Groovy class reloader is also a Groovy "compiler on demand", if we are able to make a "compiler on demand" for Java we can get THE SAME AS Groovy provides... in Java.
-As you know, as of Java 1.6 we have a http://docs.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.html[Java API] to access the compiler of your JDK.
-
-If we are able to compile and load on demand Java source files, we can be more ambitious and be able to execute Java programs with no need of a previous compilation, just
-put into a file Java code like a UNIX shell script in a similar way http://groovy.codehaus.org/Running[Groovy does], this feature provides maybe the fastest "scripting" language of the world.
-
-Why are you going to need Java as a scripting/shell language?
-
-Because:
-
-. Java is faaaast
-. Java is robust: because there is compilation on the fly, syntax errors are detected with no need of executing the offending code.
-. Java has an enormous amount of libraries
-. class files can be optionally automatically saved to avoid compilation in the next execution
-. Java 8 is around the corner providing a less verbose language
-
-If you can execute uncompiled Java code, can we get something similar to an interactive shell to execute Java code snippets? Yes of course.
-
-Do not confuse Java scripting provided by RelProxy with http://www.beanshell.org/[BeanShell], BeanShell is NOT Java, is a scripting language heavily inspired on Java < 1.5,
-running on the JVM with a nice integration with real Java, for instance in BeanShell there is no support of Java 1.5 features like generics.
-
-Finally, RelProxy is in some way similar to the famous http://zeroturnaround.com/software/jrebel/[JRebel], but is not so transparent and has more limitations. The only advantage is the price, zero, and maybe lesser memory footprint
-and better performance.
-
-That is all, welcome to dynamic Java, welcome to a more dynamic Groovy in a Java environment.
-
-
-
-== RelProxy: a fast alternative to context reloading for Java (and Groovy)
-
-Most of Java application servers (servlet containers) have the context reloading feature. Context reloading is a great feature of Java servlet/EE application servers,
-it reloads the web application usually when a .class is changed in `WEB-INF/classes`. This feature is usually used in development with the help of your favourite IDE,
-when you change a Java source file the IDE automatically compiles the file and save the .class to WEB-INF/classes, this change triggers the context reloading loading the new
-changed class.
-
-Context reloading is enough for small web applications in development phase but it becomes a productivity problem when the applications becomes big because any small change
-triggers the context reloading, the result is the context reloading being executed most of time making your system slow and producing soon a memory overflow (PermGen exception).
-Another caveat because the session is lost you must log again etc.
-
-RelProxy-Java uses a different approach, it just recompile in memory the modified class but there is no class reload (which requires a new ClassLoader). When a exposed method of
-a registered singleton in JProxy (a utility of RelProxy for Java) is called, the class reloading happens. By this way you can make big changes without consuming much memory
-and CPU, and when changes are done, just with a simple page reload the registered singleton will be called producing the class reload.
-
-RelProxy does not want to be a "full solution" for the problem of automatic class loading, with RelProxy you decide what code can be reloaded, this also reduce the impact
-of the tool because your are just going to reload just a subset of the source code of your web application (web applications are the target of the class reloading feature
-of RelProxy but other type of Java applications, for instance desktop, could be used.
-
-RelProxy can be used in development only and/or in production, in the case of production, source code going to be reloaded is included into the war file (recommended of course
-under `WEB-INF/`), you can modify the Java source file directly in production and automatically changes are detected, recompiled in memory and reloaded when needed, no .class
-change is needed, by this way you get the similar experience when you change the source code in production of a PHP, Ruby, JSP etc files without the need of restarting
-the application. If you do not want use RelProxy in production just disable it, the performance penalty is zero.
-
-RelProxy also can be used in development only accessing directly to your source files in `/src` folder (multiple source folders are allowed) with no need of uploading source code to
-production.
-
-RelProxy is an alternative to context reloading, if your application is small and you feel comfortable with context reloading you do not need the class reloading features of RelProxy
-(RelProxy also offers Java scripting), otherwise you must disable context reloading when RelProxy is enabled.
-
-
-
-== Requisites and installation
-
-RelProxy requires JDK 1.6 or upper, RelProxy have been tested on Oracle JDK 1.6, 1.7 and OpenJDK 1.7.
-
-Just uncompress the RelProxy distribution file.
-
-The distribution file has two important files:
-
-. `relproxy-X.Y.Z.jar` : needed in classpath to use RelProxy in any form.
-. `jproxysh` : needed whether command line scripting capabilities in Java are going to be used.
-
-The distribution file includes some example scripts into the folder `cmd_examples` to test the shell capabilities or RelProxy Java, executing the script
-`sh fixesforunix.sh` is recommended to define the appropriated executable permissions, then define the environment variable `JAVA_HOME` with the location of your 1.6+ JDK installation.
-
-=== Add RelProxy jar as Maven or Gradle dependency
-
-As of v0.8.3 RelProxy is registered in https://bintray.com/bintray/jcenter/[Bintray/JCenter] and Maven Central repositories.
-Add JCenter repository to your POM or Maven settings if you want to import from JCenter, in Gradle just add `jcenter()` to `repositories`.
-
-Examples for version 0.8.8:
-
-Maven POM:
-
-[source,xml]
-----
-
- com.innowhere
- relproxy
- 0.8.8
-
-----
-
-To add JCenter to your POM:
-
-[source,xml]
-----
-
-
- jcenter
- http://jcenter.bintray.com
-
-
-----
-
-Gradle build:
-
-[source,groovy]
-----
-dependencies {
- compile 'com.innowhere:relproxy:0.8.8'
-}
-----
-
-To add JCenter:
-
-[source,groovy]
-----
-repositories {
- jcenter()
-}
-----
-
-== Disabling automatic context reload
-
-RelProxy is an alternative to context reloading, use of both has no sense and makes RelProxy useless, therefore we must disable context reloading.
-
-=== In Eclipse and Tomcat
-
-In this manual Eclipse 4.4 (Luna) has been used, behaviour of previous and future versions may be the same but not tested.
-
-In Eclipse the Tomcat associated can have a configuration controlled only by Eclipse (the default mode), this configuration is only valid inside the Eclipse environment and the original configuration
-of Tomcat is untouched. By default Eclipse is configured to "Automatically publish when resources changed" for your concrete associated Tomcat, this option is required, to review this option go to
-menu `Window / Show View / Servers`, this menu option opens a view listing your servers, double click on the concrete Tomcat to show a configuration panel (if no server is associated
-to your Eclipse install a Tomcat back to Eclipse Servers view click the right button and select `New / Server` to associate the Tomcat to Eclipse).
-
-In the configuration panel click on `Publishing` drop-down and review whether is correct.
-
-image:publishing.png[Publishing, title="Publishing"]
-
-Now we are going to disable automatic context reload in a per web application/module basis (we can keep enabled in global configuration in `Server Options`).
-
-image:server_options.png[Server Options, title="Publishing"]
-
-Click on `Modules` tab.
-
-image:module_conf.png[Web Modules, title="Web Modules"]
-
-Disable the `Auto Reload` feature selecting the required module and clicking `Edit...`
-
-image:edit_web_module.png[Edit Web Module, title="Edit Web Module"]
-
-=== In NetBeans and Tomcat
-
-In this manual NetBeans 8.0.2 has been used, behaviour of previous and future versions may be the same but not tested.
-
-The author of this manual has not been able to disable context reloading feature of Tomcat in NetBeans environment. The xml archive with the `` descriptor in Tomcat installation is
-replaced with the content of `META-INF/contex.xml`, in theory just adding `reloadable=true` to `` in this file would make the job... no success, is ignored.
-
-We are able of disabling context reload avoiding the automatic synchronization of sources and deployed artifacts, two flags are involved in `Project Properties` dialog:
-
-`Build / Compile / Compile on Save`
-
-`Run / Deploy on Save`
-
-Just disabling `Deploy on Save` makes the job of avoiding .class changes and therefore context reloading.
-
-This is valid for Maven web projects and Ant based projects generated by NetBeans's wizards.
-
-The price is the lost of automatic synchronization when single source files are changed in runtime. We will explain later how we can workaround this problem.
-
-
-
-== Configuring an Eclipse web application publishing Java and/or Groovy source code on the final target war
-
-=== Dynamic Web Project
-
-We are talking about a web application created by `New / Dynamic Web Project` (or `New / Project... / Web / Dynamic Web Project`) in Eclipse with Java source code
-going to be published in production usually in a folder under `WEB-INF/` (for obvious privacy reasons).
-
-Because this folder is also a source code folder, you must add it to the project configuration `Properties / Java Build Path / Source / Add Folder`.
-
-This only affects to Java source folders, in case of using RelProxy-Groovy (GProxy) there is no need of configuring in Eclipse the folder with Groovy code (Groovy built-in compiler compiles
-Groovy files with no need of Eclipse).
-
-Unfortunately Eclipse avoids publishing Java files and they are automatically filtered
-(not the case of .groovy files) in the web application internally deployed, there is no Eclipse configuration to avoid this filtering.
-
-Installing and configuring the http://www.onehippo.org/library/development/use-filesync-eclipse-plugin-for-faster-turn-around.html[Eclipse Filesync Plugin] resolves our problem.
-
-image:install_filesync1.png[Filesync Plugin installation, title="Filesync Plugin installation"]
-
-Configure Filesync in project `Properties`.
-
-image:filesync_conf.png[Filesync configuration, title="Filesync configuration"]
-
-In this example the folder `relproxy_ex_itsnat/WebContent/WEB-INF/javaex/code` is a source code folder root containing .java files.
-
-The tricky part is the `Default target folder`. This folder is the root of the real deployed web application, the final deployed web application is created under your `workspace` folder, you can
-get the path of this folder executing in your servlet init method:
-
-[source,java]
-----
- public void init(ServletConfig config) throws ServletException
- {
- super.init(config);
-
- ServletContext context = getServletContext();
- String realPath = context.getRealPath("/");
- String inputPath = realPath + "/WEB-INF/javaex/code/";
-----
-
-The variable `inputPath` contains the path to be configured as `Default target folder` in this example.
-
-Sometimes the Filesync Plugin seems to fail, in this case you can need to force synchronization:
-
-image:filesync_force_file_sync.png[Force File Synchronization, title="Force File Synchronization"]
-
-An alternative is manual synchronization of files under `/WEB-INF` executing a custom Ant script like this:
-
-[source,xml]
-----
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-----
-
-After any modification of source code execute the synchronization task to be copied to the build directory created by Eclipse under `workspace` folder explained before.
-
-
-=== Maven based Web Project
-
-We can create a web project based on a Maven POM using the Maven archetype `maven-archetype-webapp` selecting `New / Other / Maven / Maven Project`, set in `Filter`
-the value `maven-archetype-webapp`.
-
-In project `Properties / Java Build Path / Libraries / Add Library` add the server for instance `Apache Tomcat v7`.
-
-The header of web.xml generated by Maven is a bit old (based on `DOCTYPE`), replace it with something like this (servlet 2.5, 3.0 is also valid for Tomcat v7):
-
-[source,xml]
-.web.xml
-----
-
-
-...
-
-----
-
-Follow the same steps described for an Eclipse Dynamic Web Project, yes in spite of most of things are defined in Maven we must repeat the same on Eclipse `Project Properties` dialogs,
-(for instance register the extra source code folders).
-
-Because we are going to publish source code files (located in some place under `WEB-INF/`) to the final war we need to explain to Maven where are located these extra folders
-to be also included in compilation and copied to the final war, this configuration is done adding the extra source code folders as resources.
-
-At the time of writing ItsNat is not in Maven Central repository, you must manually include it in your dependencies as a `system` dependency, and copy the jar to the `WEB-INF/lib`
-folder.
-
-The following POM is a simple example of a ItsNat web application using RelProxy (v0.8.8) and including a published source code folder, `src/main/webapp/WEB-INF/code`, able to
-contain reloadable source code (remember to add `ItsNat-1.3.1.jar` to the `WEB-INF/lib` folder):
-
-[source,xml]
-.pom.xml
-----
-
- 4.0.0
-
- com.innowhere
- relproxy_ex_itsnat_maven
- war
- 0.1-SNAPSHOT
- relproxy_ex_itsnat_maven Maven Webapp
- https://github.com/jmarranz/relproxy/
-
-
- UTF-8
-
-
-
-
-
- javax.servlet
- servlet-api
- 2.5
- provided
-
-
-
- javax.servlet.jsp
- jsp-api
- 2.1
- provided
-
-
-
-
-
-
- com.innowhere
- relproxy
- 0.8.8
-
-
-
- ItsNat
- ItsNat-jar
- 1.3.1
- system
- ${basedir}/src/main/webapp/WEB-INF/lib/ItsNat-1.3.1.jar
-
-
-
- org.apache.xmlgraphics
- batik-dom
- 1.7
-
-
-
- org.apache.xmlgraphics
- batik-xml
- 1.7
-
-
-
- org.apache.xmlgraphics
- batik-util
- 1.7
-
-
-
- net.sourceforge.nekohtml
- nekohtml
- 1.9.12
-
-
-
- xalan
- serializer
- 2.7.1
-
-
-
- org.codehaus.groovy
- groovy-all
- 2.1.6
-
-
-
-
-
- relproxy_ex_itsnat_maven
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 2.0.2
-
- 1.6
- 1.6
- ${project.build.sourceEncoding}
-
-
-
-
- org.apache.maven.plugins
- maven-resources-plugin
- 2.4.3
-
- ${project.build.sourceEncoding}
-
-
-
-
-
-
-
- src/main/webapp/WEB-INF/groovyex/code
-
-
- src/main/webapp/WEB-INF/javaex/code
-
-
-
-
-
-
-----
-
-In Eclipse there is no need of using org.codehaus.mojo:build-helper-maven-plugin plug-in (Maven support is "especial" in Eclipse), folders specified in are
-recognized as source folders.
-
-If you have several folders with source code (RelProxy supports multiple hot reloadable root folders), add more elements, for instance:
-
-[source,xml]
-----
-
-
- src/main/webapp/WEB-INF/groovyex/code
-
-
- src/main/webapp/WEB-INF/javaex/code
-
-
- src/main/webapp/WEB-INF/javaex/code2
-
-
-----
-
-Because we need to synchronize source code into `/WEB-INF` Filesync or this Ant file will help us:
-
-[source,xml]
-.sync.xml
-----
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-----
-
-
-== Configuring a NetBeans web application publishing Java and/or Groovy source code on the final target war
-
-Remember you must avoid context reloading disabling first `Run / Deploy on Save` in `Project Properties` dialog.
-
-=== Web Project based on Ant created by NetBeans
-
-A conventional (not Maven) web project is created in NetBeans selecting the menu `File / New Project / Java Web / Web Application`.
-
-By default he generated Ant file filters .java files under `WEB-INF/` when deploying, to avoid this filtering just add to the build.xml:
-
-[source,xml]
-.build.xml
-----
-
-
-
-
-
-----
-
-Fortunately in this type of Ant based project, if the option `Project Properties / Build / Compile / Compile on Save` is enabled, NetBeans takes (by using Ant) care of automatic
-synchronization of resources of `/web/WEB-INF` and the same folder under `/build`, this includes .java files because we have avoided this filtering. There is no need
-of explicit synchronization by using Ant tasks.
-
-=== Web Project based on Maven
-
-A Maven web project is created in NetBeans selecting the menu `File / New Project / Maven / Web Application`.
-
-Take a look again to the chapter about Eclipse Maven based web applications, the Maven POM structure is the same for NetBeans, remember you must specify extra source code folders
-under `WEB-INF/` adding them as ``s.
-
-Because the default structure of Maven, on development time when deploying a web application, Maven deploys under the `target/projectname` folder
-the final web application. Changed source files under `src/webapp` in runtime are not detected by RelProxy because the real files being used
-are really below `target/projectname` unless NetBeans automatically synchronizes files between both file trees. Effectively NetBeans automatically copies the modified file
-to the `target/projectname`, but unfortunately excluding .java (and .groovy) files.
-
-In theory enabling `Project Properties / Run / Deploy on Save` does the job but enables automatic context reloading.
-
-One simple solution is adding a special Ant task to synchronize the source files to the same files in `target/projectname`. Call this task after hot source code modification.
-
-For instance:
-
-[source,xml]
-.sync.xml
-----
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-----
-
-== Configuring a NetBeans or Eclipse web application NOT publishing Java and/or Groovy source code on the final target war
-
-As you have seen adding source code files under `WEB-INF/` is very problematic, we have needed some tricks and workarounds to synchronize these source folders to the final deployed
-web application.
-
-If you are not going to publish source code to production and you just need hot reload source code under your `/src/main/java` folder in Maven or `src/java` in NetBeans or `/src`
-in Eclipse, that is only in development phase, you do not need synchronization tricks because you tell RelProxy to directly access to the original source being modified for you
-and RelProxy recompiles and loads your changes in memory.
-
-Both types of web applications, publishing source code to war and direct access to normal source code, are going to be shown you using concrete examples.
-
-
-== GProxy or how to be able to reload Groovy classes on the Java environment
-
-`com.innowhere.relproxy.gproxy.GProxy` is the main Java class of RelProxy to provide this feature, with `GProxy` you can create Java proxies for Groovy objects because
-a `java.lang.reflect.Proxy` wrapper is passed instead of the original Groovy object, the original Groovy object is retained under the hood and method calls to the proxy
-are redirected to the real object calling the corresponding method using reflection. When the source code of the Groovy class changes GProxy automatically reloads the Groovy
-class and creates a new object to replace the old one, the fields of the original object are got and re-set to the new object to keep the state (number of fields and types
-must be the same otherwise reloading is not possible and a redeploy is required).
-
-The following code is an example of how to use RelProxy along with ItsNat web framework, this code is included in the examples of RelProxy (`relproxy_ex_itsnat` or `relproxy_ex_itsnat_maven`).
-
-The `servlet` variable is a servlet object containing a just configured `groovy.util.GroovyScriptEngine`, the setting up of this utility object is omitted:
-
-
-[source,groovy]
-.groovy_servlet_init.groovy
-----
-package example.groovyex;
-
-import org.itsnat.core.http.ItsNatHttpServlet;
-import org.itsnat.core.tmpl.ItsNatDocumentTemplate;
-import org.itsnat.core.event.ItsNatServletRequestListener;
-import groovy.util.GroovyScriptEngine;
-import java.lang.reflect.Method;
-import com.innowhere.relproxy.RelProxyOnReloadListener;
-import com.innowhere.relproxy.gproxy.GProxy;
-import com.innowhere.relproxy.gproxy.GProxyGroovyScriptEngine;
-import com.innowhere.relproxy.gproxy.GProxyConfig;
-
-
-GroovyScriptEngine groovyEngine = servlet.getGroovyScriptEngine();
-
-def gproxyGroovyEngine = {
- String scriptName -> return (java.lang.Class)groovyEngine.loadScriptByName(scriptName)
- } as GProxyGroovyScriptEngine;
-
-def reloadListener = {
- Object objOld,Object objNew,Object proxy, Method method, Object[] args ->
- println("Reloaded " + objNew + " Calling method: " + method)
- } as RelProxyOnReloadListener;
-
-def gpConfig = GProxy.createGProxyConfig();
-gpConfig.setEnabled(true)
- .setRelProxyOnReloadListener(reloadListener)
- .setGProxyGroovyScriptEngine(gproxyGroovyEngine);
-
-GProxy.init(gpConfig);
-
-
-String pathPrefix = context.getRealPath("/") + "/WEB-INF/groovyex/pages/";
-
-def docTemplate;
-docTemplate = itsNatServlet.registerItsNatDocumentTemplate("groovyex","text/html", pathPrefix + "groovyex.html");
-
-def db = new FalseDB();
-
-ItsNatServletRequestListener listener = GProxy.create(new example.groovyex.GroovyExampleLoadListener(db), ItsNatServletRequestListener.class);
-docTemplate.addItsNatServletRequestListener(listener);
-
-----
-
-
-Let's explain the previous code:
-
-[source,groovy]
-----
-def gproxyGroovyEngine = {
- String scriptName -> return (java.lang.Class)groovyEngine.loadScriptByName(scriptName)
- } as GProxyGroovyScriptEngine;
-----
-
-Defines a listener needed by `GProxy` to indirectly call the `groovy.util.GroovyScriptEngine` to load classes, take a look to the signature of `GProxyGroovyScriptEngine`
-there is no dependency with `groovy.*` packages, this is why you can use RelProxy in pure Java projects with no Groovy dependency in spite of Groovy support.
-
-
-[source,groovy]
-----
-def reloadListener = {
- Object objOld,Object objNew,Object proxy, Method method, Object[] args ->
- println("Reloaded " + objNew + " Calling method: " + method)
- } as RelProxyOnReloadListener;
-----
-
-Defines an optional `RelProxyOnReloadListener` listener to be called when Groovy classes have been reloaded because some change has happened in the source code managed by RelProxy.
-
-An object implementing this interface may be registered on RelProxy to listen when a method of the proxy object has been called (this example only includes one method
-exposed by the interface, but nothing prevents of adding more methods to the interface/implementation) and the class of the original object associated has been reloaded
-(a new "original" object based on the new class was created to replace it).
-
-When you perform a source code change in source code managed by RelProxy the first time this method is called is the signal that changes has been detected and reloaded
-accordingly.
-
-This interface and behavior is not `GProxy` specific and will be also used in `JProxy` for Java.
-
-[source,groovy]
-----
-def gpConfig = GProxy.createGProxyConfig();
-gpConfig.setEnabled(true)
- .setRelProxyOnReloadListener(reloadListener)
- .setGProxyGroovyScriptEngine(gproxyGroovyEngine);
-
-GProxy.init(gpConfig);
-----
-
-Configures `GProxy`, now it is ready to proxy Groovy objects.
-
-Take a look to the optional `setEnabled(true)` configuration call, `GProxy` is enabled by default, this means proxied Groovy objects are instrumented for hot reload.
-Calling `setEnabled(false)` tells `GProxy` to ignore any other configuration, `GProxy` is disabled and no proxy is created calling `GProxy.create`, the original Groovy
-objects will be returned with absolutely no performance penalty, this is the preferred configuration in production whether you do not want hot class reload in production.
-
-The final code:
-
-[source,groovy]
-----
-def db = new FalseDB();
-
-ItsNatServletRequestListener listener = GProxy.create(new example.groovyex.GroovyExampleLoadListener(db), ItsNatServletRequestListener.class);
-docTemplate.addItsNatServletRequestListener(listener);
-----
-
-is an example of proxying a `example.groovyex.GroovyExampleLoadListener` object and registering the returned Java proxy into the ItsNat infrastructure.
-The class `example.groovyex.GroovyExampleLoadListener` implements the ItsNat standard interface `ItsNatServletRequestListener` implementing the method
-`processRequest(ItsNatServletRequest request, ItsNatServletResponse response)` this method is called by ItsNat when a page rendered by the template is loaded, the proxy object receives this call and forwards this call
-to the latest class loaded, we are going to see more details later.
-
-Let's go to take a look to `example.groovyex.GroovyExampleLoadListener`:
-
-[source,groovy]
-.GroovyExampleLoadListener.groovy
-----
-package example.groovyex;
-
-import org.itsnat.core.event.ItsNatServletRequestListener;
-import org.itsnat.core.ItsNatServletRequest;
-import org.itsnat.core.ItsNatServletResponse;
-import example.groovyex.FalseDB;
-
-class GroovyExampleLoadListener implements ItsNatServletRequestListener
-{
- def db
-
- GroovyExampleLoadListener()
- {
- }
-
- GroovyExampleLoadListener(FalseDB db) // Explicit type tells Groovy to reload FalseDB class when changed
- {
- this.db = db;
- }
-
- void processRequest(ItsNatServletRequest request, ItsNatServletResponse response)
- {
- println("GroovyExampleLoadListener 4 ");
-
- new example.groovyex.GroovyExampleDocument(request.getItsNatDocument(),db);
- }
-}
-----
-
-To understand this code let's to explain how ItsNat works, the method `processRequest` is called every time a page is loaded specifying the same ItsNat template,
-because this listener was registered as its load processor.
-
-When RelProxy (through `groovy.util.GroovyScriptEngine`) detects the source code of the class `GroovyExampleLoadListener` or dependent classes like `GroovyExampleDocument`
-have changed, all classes with associated hot reloadable source, are reloaded and a new `ClassLoader` is created for them, next calls to `GroovyExampleLoadListener` proxy
-will use the new loaded class and the same with dependent classes.
-
-However a concrete `GroovyExampleLoadListener` object was used to register, how can we reload a class with one live object already created?
-
-The `GroovyExampleLoadListener` object was the one proxied, the class of this object is reloaded when a source change is detected (or any related class) because this is the
-objective of RelProxy, but this object can have fields pointing to objects usually loaded _before_ registering/proxying the `GroovyExampleLoadListener` object. The classes
-of these attribute objects may be also reloaded but the new version is not effective because referenced objects are usually being used in other places, if we re-create these
-objects we are creating new instances for instance of objects designed to be singletons. This is the case of the `db` attribute of
-class `FalseDB`, this attribute references a concrete `FalseDB` object not able to be automatically reloaded in spite of the Groovy `FalseDB` class could be reloaded.
-This is why in case of the proxied object `GroovyExampleLoadListener`, RelProxy recreates the object based on the new loaded class by calling the default constructor and
-*re-setting the attributes*, by this way the new object is based on the new class containing the same attribute objects defined before, you cannot add, remove or change
-the type of attributes, if you do so RelProxy will not be able to hot reload and a new redeploy is needed.
-
-The proxied class usually creates new objects based on dependent classes to execute some task, if no object of these dependent classes is "saved" and/or used outside of
-proxied environment RelProxy can reload dependent classes with no problem.
-
-This is the case of the class `GroovyExampleDocument` and dependent classes (see the source code).
-
-Other classes and interfaces like `ItsNatServletRequest` or `ItsNatServletResponse` are not reloaded in this example because they are ItsNat based and source code is not
-present in Groovy environment. `FalseDB` class could be reloaded but reloading will fail because the proxied object (`GroovyExampleLoadListener`) holds an attribute `db` of this
-class, RelProxy will say you the reloading process has been failed and a redeploy is recommended to effectively use the new version of the class.
-
-In summary, in this ItsNat example, when source code of `GroovyExampleLoadListener` or dependent classes with source code controlled by RelProxy change, all of these classes are recompiled
-and reloaded by Groovy when changed. When the `processRequest` method of the proxied `GroovyExampleLoadListener` object is called because an end user is reloading the related web page, `GProxy` detects
-the singleton has been reloaded and recreates the `GroovyExampleLoadListener` object with the new +Class+ re-setting the fields and finally
-the `processRequest` method is called and method processing is done using the new version of dependent classes.
-
-Finally we have been able to reload Groovy classes mixed in a Java environment.
-
-== JProxy or how to be able to reload Java classes without using Java agents
-
-Java hot reloadable proxies are very similar to Groovy support of RelProxy, in this case the task of detecting source changes, recompiling and reloading is fully done by RelProxy
-(in case of Groovy provided `groovy.util.GroovyScriptEngine` does most of this work).
-
-`com.innowhere.relproxy.jproxy.JProxy` is the main Java class of RelProxy for hot reload of pure Java, with `JProxy` you can create Java `java.lang.reflect.Proxy` proxies wrapping
-your original objects to be passed to listeners, the original object is retained under the hood and method calls to the proxy are redirected to the real object calling the
-corresponding method using reflection. When the source code of a monitored Java file is changed, it is automatically recompiled in memory. When the `processRequest` method of
-the proxied `JProxyExampleLoadListener` object is called because an end user is reloading the related web page, `JProxy` detects something has changed and reload all monitored
-classes with a new `ClassLoader`, because the singleton class has been reloaded JProxy recreates the `JProxyExampleLoadListener` object with the new +Class+ re-setting the fields
-to keep the state (number of fields and types must be the same otherwise reloading is not possible and a redeploy is required) and finally the `processRequest` method is called and method processing
-is done using the new version of dependent classes.
-
-As you can see reloading only happens when hot reloadable classes are going to be used, only recompiling is done when some file is changed, this is a performance and memory
-improvement over the typical "context reloading per file save".
-
-The following code is an example of how to use `JProxy` along with ItsNat web framework, this code is part of the RelProxy examples (`relproxy_ex_itsnat` or `relproxy_ex_itsnat_maven`)
-basically doing the same as the Groovy example:
-
-
-[source,java]
-.JProxyExampleServlet.java
-----
-package example.javaex;
-
-import java.io.File;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.tools.Diagnostic;
-import javax.tools.DiagnosticCollector;
-import javax.tools.JavaFileObject;
-
-import org.itsnat.core.event.ItsNatServletRequestListener;
-import org.itsnat.core.http.HttpServletWrapper;
-import org.itsnat.core.tmpl.ItsNatDocumentTemplate;
-import com.innowhere.relproxy.RelProxyOnReloadListener;
-import com.innowhere.relproxy.jproxy.JProxy;
-import com.innowhere.relproxy.jproxy.JProxyCompilerListener;
-import com.innowhere.relproxy.jproxy.JProxyConfig;
-import com.innowhere.relproxy.jproxy.JProxyDiagnosticsListener;
-import com.innowhere.relproxy.jproxy.JProxyInputSourceFileExcludedListener;
-
-
-/**
- *
- * @author jmarranz
- */
-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 compilationOptions = Arrays.asList(new String[]{"-source","1.6","-target","1.6"});
- long scanPeriod = 300;
-
- 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);
- }
- };
-
- JProxyDiagnosticsListener diagnosticsListener = new JProxyDiagnosticsListener()
- {
- @Override
- public void onDiagnostics(DiagnosticCollector diagnostics)
- {
- List> 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++;
- }
- }
- };
-
- 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);
-
-
- 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);
- }
-
-}
-----
-
-There is more code than Groovy code because `GroovyScriptEngine` setting up was omitted (not specific of RelProxy) and now some configuration options are shown in spite of they
-may be optional.
-
-Let's explain the previous code:
-
-[source,java]
-----
- 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 is an example of JProxy configuration.
-
-* `setEnabled(boolean)` configuration method is the same as `GProxy`, when setting to false other configuration options are ignored, there is no hot reload and proxying and
-performance penalty is zero.
-
-* `setRelProxyOnReloadListener(proxyListener)` is the same as `GProxy` in fact the same interface `RelProxyOnReloadListener` is shared between `GProxy` and `JProxy`.
-
-* `setInputPath(inputPath)` defines where the source code files of hot reloadable classes is. The variant method `setInputPaths(String[])` allows registering
-several root folders and `setJProxyInputSourceFileExcludedListener(JProxyInputSourceFileExcludedListener)` allows excluding concrete files.
-
-* `setJProxyInputSourceFileExcludedListener(excludedListener)` optionally defines whether the specified folder or file is excluded in the recompiling detection. In this example nothing is excluded.
-
-* `setScanPeriod(scanPeriod)` defines the period (in ms) between checks of timestamps of source code files to detect changes.
-
-* `setClassFolder(classFolder)` optionally defines where to save, as .class files, the bytecode resulting of re-compiling modified source files in runtime.
-By this way the next time the application is started .class files are aligned with source files and no runtime compilation is needed (class folder of course must be in
-classpath).
-
-* `setCompilationOptions(compilationOptions)` optionally sets the list of options you want for compiling phase, these are the same kind of options you would provide to the
-http://docs.oracle.com/javase/6/docs/technotes/tools/windows/javac.html[javac command], internally the
-http://docs.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.html[Java compiler API] receives this parameters and the reason of the required format.
-
-* `setJProxyCompilerListener(compilerListener)` optionally registers a listener to be called when a file is going to be compiled.
-
-* `setJProxyDiagnosticsListener(diagnosticsListener)` optionally registers the `JProxyDiagnosticsListener` listener to be executed when some warning or error happens compiling
-Java code, when providing null or not called RelProxy uses a default listener very similar to this example.
-
-
-The final code:
-
-[source,java]
-----
- FalseDB db = new FalseDB();
-
- ItsNatServletRequestListener listener = JProxy.create(new example.javaex.JProxyExampleLoadListener(db), ItsNatServletRequestListener.class);
- docTemplate.addItsNatServletRequestListener(listener);
-----
-
-Is symmetric to Groovy counterpart, it is the same example and the same expected behavior of RelProxy but all in Java.
-
-Anyway this is the code of `JProxyExampleLoadListener`:
-
-[source,java]
-.JProxyExampleLoadListener.java
-----
-package 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 4 " + this.getClass().getClassLoader().hashCode());
-
- new example.javaex.JProxyExampleDocument(request,(ItsNatHTMLDocument)request.getItsNatDocument(),db);
- }
-}
-----
-
-As of version 0.8.6 RelProxy also supports hot reload of inner classes including anonymous inner classes. An example of ItsNat code:
-
-[source,java]
-.JProxyExampleLoadListener.java
-----
-EventListener listener = new EventListener()
-{
- @Override
- public void handleEvent(Event evt)
- {
- ...
- }
- };
-
-Element buttonElem = doc.getElementById("buttonId");
-((EventTarget)buttonElem).addEventListener("click", JProxy.create(listener, EventListener.class) ,false);
-----
-
-Obviously the container (enclosing) class of the inner class must be reloadable.
-
-=== Use of JProxy with multiple servlets
-
-In the previous JProxy example we have supposed one single servlet requiring class reloading and context reloading disabled.
-
-If you have more servlets or you are a purist developer, you can use a `ServletContextListener`:
-
-[source,java]
-.JProxyServletContextListener.java
-----
-...
-public class JProxyServletContextListener implements ServletContextListener
-{
- @Override
- public void contextInitialized(ServletContextEvent sce)
- {
- System.out.println("ServletContextListener contextInitialized");
-
- ServletContext context = sce.getServletContext();
- ...
- JProxy.init(jpConfig);
- }
-
- @Override
- public void contextDestroyed(ServletContextEvent sce)
- {
- System.out.println("ServletContextListener contextDestroyed");
- JProxy.stop();
- }
-}
-----
-
-Registered on your `web.xml`:
-
-[source,xml]
-.web.xml
-----
-
-
- example.javaex.JProxyServletContextListener
-
-
-
-----
-
-The `stop()` call is used to stop the timer checker of source code changes, useful to avoid memory leaks when the context is reloaded and avoid warnings when the
-servlet container is stopping.
-
-Finally in your servlet classes only register your singletons:
-
-[source,java]
-----
- @Override
- public void init(ServletConfig config) throws ServletException
- {
- super.init(config);
-
- ServletContext context = config.getServletContext();
-
- 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);
- }
-----
-
-
-=== Starting and stopping class change detection and reloading in JProxy
-
-You can reduce to zero the footprint of RelProxy in production setting `setEnabled(boolean)` to false, however if you are a brave guy or girl and you want to make also hot changes
-in production... `JProxy.start()` and `JProxy.stop()` methods are for you.
-
-Remember we must to define the period between source files checking for changes calling `setScanPeriod(scanPeriod)`, RelProxy defines behind the scene a `java.util.Timer` for this
-task, of course every time source code is checked for changes needs some time and CPU use, because there are synchronizations between source code checking and proxies use, a very small performance penalty
-happens when checking source code. This is why we can `stop` source code checking if we are not able to make source code changes anymore reducing performance penalty to minimum, and we can
-call `start` again to detect any source change.
-
-You can call several times to `JProxy.start()` and `JProxy.stop()` methods, if nothing is going to be done nothing is done without errors (both methods return true
-when a state change was effective), and they are thread safe.
-
-Call ever to `stop()` in your `ServletContextListener` in the `contextDestroyed(ServletContextEvent)` method.
-
-
-== Using JProxy only in development time with no need of publishing code (a GWT example)
-
-In previous chapters we have added new source code folders below `WEB-INF/` folder, this configuration is very useful in production to be able to hot change
-your Java code, of course in production time you can remove these folders avoiding publishing source code before packaging to `war` and with a simple call `setEnabled(false)`
-disable JProxy with zero performance penalty, this makes JProxy helpful in development only but as you can easily figure out, adding source code under `WEB-INF/` folder
-is not a good idea if you are not going to use this code in production.
-
-With JProxy is not necessary to put the source code going to be reloaded under `WEB-INF/`, you can modify Java source code and reload it located in conventional source code folders.
-
-Because JProxy is going to directly access to original source code, the folder synchronizing problems are gone in this use case.
-
-We are going to illustrate this capability with a GWT RPC example using Eclipse. Besides how to use JProxy in a GWT-RPC project, in this chapter we are going to learn
-how we can exclude source files from the hot class reload system of RelProxy/JProxy because we are going to need this feature.
-
-This example is for development phase only, nothing prevents of appliying both strategies because JProxy allows multiple source folders to monitor by using `JProxyConfig.setInputPaths(String[])`.
-
-In GWT, JProxy only can be used to reload Java code executed in server, this is why we are going to apply JProxy to a GWT-RPC project (that is a client-server web application).
-
-Install http://eclipse.org[Eclipse] (Eclipse 4.4 Luna was used for this example), install the https://developers.google.com/eclipse/docs/download[Google Plugin for Eclipse] (version 4.4 was used),
-only install GWT dependencies if you want (there is no need of Android and Google App Engine parts).
-
-Download RelProxy distribution file and copy the `relproxy-x.y.z.jar` to `/war/WEB-INF/lib/`.
-
-Select in Eclipse the menu option `New / Other... / Google/ Web Application Project` to create a GWT-RPC sample project (Google App Engine is not needed).
-
-There is no need of disabling context reloading, it seems is already disabled in the default configuration of GWT.
-
-In this example we have created the project with name `relproxy_ex_gwt` and package `com.innowhere.relproxyexgwt`, this is
-the structure of the generated source code:
-
-++++
-
-++++
-
-
-We are only be able to reload classes executed in server, that is, classes below `server/` folder. This why the class `GreetingServiceImpl.java` is our focus,
-this is the generated code:
-
-[source,java]
-.GreetingServiceImpl.java
-----
-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 {
-
- public 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 + "!
I am running " + serverInfo + ".
It looks like you are using: " + userAgent;
- }
-
- /**
- * 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("&", "&").replaceAll("<", "<").replaceAll(">", ">");
- }
-}
-
-----
-
-This class is a servlet created to receive RPC requests from client following the interface pattern of the interface `GreetingService` shared by client and server code.
-We are not going to try to reload this servlet because to use JProxy we need a reloadable singleton implementing an interface registered in JProxy, therefore
-we are deeply transforming `GreetingServiceImpl`:
-
-[source,java]
-.GreetingServiceImpl.java
-----
-package com.innowhere.relproxyexgwt.server;
-
-import java.io.File;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.tools.Diagnostic;
-import javax.tools.DiagnosticCollector;
-import javax.tools.JavaFileObject;
-
-import com.google.gwt.user.server.rpc.RemoteServiceServlet;
-import com.innowhere.relproxy.RelProxyOnReloadListener;
-import com.innowhere.relproxy.jproxy.JProxy;
-import com.innowhere.relproxy.jproxy.JProxyConfig;
-import com.innowhere.relproxy.jproxy.JProxyDiagnosticsListener;
-import com.innowhere.relproxy.jproxy.JProxyInputSourceFileExcludedListener;
-import com.innowhere.relproxy.jproxy.JProxyCompilerListener;
-import com.innowhere.relproxyexgwt.client.GreetingService;
-
-/**
- * The server-side implementation of the RPC service.
- */
-@SuppressWarnings("serial")
-public class GreetingServiceImpl extends RemoteServiceServlet implements
- GreetingService {
-
- protected GreetingServiceDelegate delegate;
-
- public void init(ServletConfig config) throws ServletException {
-
- super.init(config);
-
- ServletContext context = config.getServletContext();
-
- String inputPath = context.getRealPath("/") + "/../src/";
- if (!new File(inputPath).exists())
- {
- System.out.println("RelProxy is disabled, detected production mode ");
- return;
- }
-
- 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");
- }
- }
- };
-
- String classFolder = null; // Optional: context.getRealPath("/") + "/WEB-INF/classes";
- Iterable compilationOptions = Arrays.asList(new String[]{"-source","1.6","-target","1.6"});
- long scanPeriod = 200;
-
- 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(){
- @Override
- public void beforeCompile(File file)
- {
- System.out.println("Before compile: " + file);
- }
-
- @Override
- public void afterCompile(File file)
- {
- System.out.println("After compile: " + file);
- }
- };
-
- JProxyDiagnosticsListener diagnosticsListener = new JProxyDiagnosticsListener()
- {
- public void onDiagnostics(DiagnosticCollector diagnostics)
- {
- List> 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++;
- }
- }
- };
-
- 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
-
- 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();
- }
-}
-
-----
-
-Let's review this JProxy-ready class. `GreetingServiceImpl` is a singleton in practice because is a servlet, therefore this attribute:
-
-[source,java]
-----
-protected GreetingServiceDelegate delegate;
-----
-
-which hold the reloadable singleton registered on:
-
-[source,java]
-----
-this.delegate = JProxy.create(new GreetingServiceDelegateImpl(this), GreetingServiceDelegate.class);
-----
-
-As you can see we have created the Java file `GreetingServiceDelegateImpl.java` the class to hold the singleton going to be reloaded, implementing
-the interface `GreetingServiceDelegate`. JProxy returns a proxy object "implementing" `GreetingServiceDelegate` exposed to the non-reloadable world.
-
-Take a look to this listener, in the previous example it was trivial, in this case is very important:
-
-[source,java]
-----
- 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");
- }
- }
- };
-----
-
-Registered on:
-
-[source,java]
-----
- .setJProxyInputSourceFileExcludedListener(excludedListener)
-----
-
-This listener filters the Java source files that must be ignored by RelProxy/JProxy even when modified.
-
-Because JProxy creates a new ClassLoader and reloads on it all hot-reloadable classes when someone is modified, classes inside `client/` and `shared/` folders must not be reloadable
-because has no sense in GWT.
-
-When a folder inside a declared source folder of reloadable classes specified in configuration is going to be inspected for changed classes, the method `isExcluded` is called to
-check whether the complete folder must be excluded, this is very useful for big projects with a lot of not reloadable files. In this case classes inside `client/` or `shared/`
-are excluded. If a folder is not excluded, child files and folders into this folder are asked for excluding calling `isExcluded`, the class `GreetingServiceImpl` cannot be reloaded
-because it is a servlet and cannot be registered in JProxy because is already in use by the JavaEE servlet system. Finally `GreetingServiceDelegate.java` cannot be reloaded
-because is the interface exposed to the non-reloadable world.
-
-In summary only server/ classes can be reloaded excluding the servlet class `GreetingServiceImpl.java` and `GreetingServiceDelegate.java`.
-
-In this example there is only specified a root source code folder, RelProxy allows several root source code folder `JProxyConfig.setInputPahts(String[])` instead of `JProxyConfig.setInputPaht(String)`,
-the parameter `File rootFolder` specify the root source code folder containing the folder or file to apply excluding rules, this parameter can help you to define very complex
-excluding scenarios with several root source code folders. The web application `relproxy_test_itsnat` used to test RelProxy contains a complex excluding scenario with three root source folders.
-
-This is the code of `GreetingServiceDelegate` :
-
-[source,java]
-.GreetingServiceDelegate.java
-----
-package com.innowhere.relproxyexgwt.server;
-
-public interface GreetingServiceDelegate {
-
- public String greetServer(String input) throws IllegalArgumentException;
-
-}
-----
-
-And the code of `GreetingServiceDelegateImpl.java`, basically a copy/paste of the original servlet code.
-
-[source,java]
-.GreetingServiceDelegateImpl.java
-----
-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;
- }
-
- public 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 = parent.getServletContext().getServerInfo();
- String userAgent = parent.getThreadLocalRequestPublic().getHeader("User-Agent");
-
- // Escape data from the client to avoid cross-site script vulnerabilities.
- input = escapeHtml(input);
- userAgent = escapeHtml(userAgent);
-
- return "Hello, " + input + "!
I am running " + serverInfo
- + ".
It looks like you are using: " + userAgent;
- }
-
- /**
- * 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("&", "&").replaceAll("<", "<")
- .replaceAll(">", ">");
- }
-}
-
-----
-
-Run this example (`Run As/Web Application GWT Super Dev Mode`), open this URL http://127.0.0.1:8888/Relproxy_ex_gwt.html[http://127.0.0.1:8888/Relproxy_ex_gwt.html] in your browser and a screen like this is shown:
-
-image:browser_1.png[Fig 1, title="Fig 1"]
-
-Click on `Send to Server`:
-
-image:browser_2.png[Fig 2, title="Fig 2"]
-
-Click on the `Close` button.
-
-Now we are going to modify on the fly the Java code of `GreetingServiceDelegateImpl`, just change "Hello" by "Hello BROTHER" and save:
-
-[source,java]
-----
- return "Hello BROTHER, " + input + "!
I am running " + serverInfo
- + ".
It looks like you are using: " + userAgent;
-----
-
-Back to browser, click again on "Send to Server":
-
-image:browser_3.png[Fig 3, title="Fig 3"]
-
-As you can see in this case no page reload has been necessary because the requisite is to call the proxied method to reload classes, this call was made by a AJAX/RPC call.
-
-In this example we made a very simple method change, adding more methods is not a problem but most of the time you will need to add new fields related to new classes,
-because `GreetingServiceDelegateImpl` is a singleton we cannot add, remove or change names and types of the fields of this class, to overcome this severe limitation
-create new classes avoiding the singleton pattern and move the code to them. Code something like this:
-
-[source,java]
-.GreetingServiceDelegateImpl
-----
- public String greetServer(String input) throws IllegalArgumentException {
- return new GreetingServiceProcessor(this).greetServer(input);
- }
-----
-
-Declared fields of `GreetingServiceProcessor` can change with no problem because this class can be reloaded and is instantiated by any call to
-`GreetingServiceDelegateImpl.greetServer()` with fresh data.
-
-== Solving jar manifest configuration problems in JProxy
-
-When developing a Liferay 6.2 example using RelProxy a weird problem was manifested, RelProxy (JProxy) internally makes a call like this:
-
-[source,java]
-----
- Enumeration res = classLoader.getResources("javax/portlet");
-----
-
-This call is expected to return a list of URL-JAR pointing to `.class` files with package `javax.portlet`, in Liferay 6.2 the jar containing these classes is `portlet.jar`. In spite
-of this jar is defined in the classpath of the `ClassLoader`, nothing is returned. To fix this problem we just need to decompress this jar and add `Name: javax/portlet` to the file
-`META-INF/MANIFEST.MF` and package again.
-
-As you have realized, this solution is "dirty" and problematic with "jar downloaders" like any build tool downloading Maven artifacts. This is why JProxy provides a workaround
-allowing direct specification of the problematic jars (use absolute paths), when necessary RelProxy uses the "brute force" to locate the .class of the required package "manually" inspecting
-the provided jars. JProxy adds a new configuration method to specify these jars:
-
-[source,java]
-----
- JProxyConfig.setRequiredExtraJarPaths(String[] inputJarPaths)
-----
-
-This problem has been found in a jar in Liferay, but nothing prevents similar problematic jars in other tools. To see this problem fixed in Liferay take a look to the `JProxyServletContextListener.java` file of http://github.com/jmarranz/relproxy_examples/tree/master/relproxy_ex_liferay-portlet[Liferay Example] included in http://github.com/jmarranz/relproxy_examples[RelProxy Examples].
-
-This problem is uncommon, if JProxy throws an error of a class not found and this class is in a jar known by the `ClassPath` used to load JProxy,
-suspect this problem and try to add explicitly the path of the problematic jar.
-
-== Identity of returned proxies
-
-A proxy object implements the specified interfaces (in practice only one is important), you can call to any methods of the interface, this call is forwarded by RelProxy
-to the original or reloaded object. Because a proxy object is also an `Object`, the methods `equals(Object)` and `hashCode()` may be also called, these calls
-are forwarded to the wrapped object of the proxy.
-
-When calling `equals(Object)` method RelProxy detects the special case of passing a proxy parameter, in this case RelProxy obtains the current associated object to the proxy parameter
-and passes this object to the equals method. By this way we are able to check the identity of two objects indirectly using two proxy objects. This feature
-is very useful in collections when registering a proxy instead of the original object, if another proxy object associated to the same original object is used for instance to remove
-from collection, the `equals(Object)` method is correctly called passing the original object.
-
-Example:
-
-[source,java]
-----
- ItsNatServletRequestListener original = new example.javaex.JProxyExampleLoadListener(db);
- ItsNatServletRequestListener proxy = JProxy.create(original, ItsNatServletRequestListener.class);
- ItsNatServletRequestListener proxy2 = JProxy.create(original, ItsNatServletRequestListener.class);
- System.out.println("EQUALS TEST (true if not reloaded): " + (proxy.equals(proxy2)));
-----
-
-== A new shell scripting language named Java
-
-When we think on a shell scripting language we think on `sh` or `csh`, or maybe on the scripting language of Windows Console (based on the old MSDOS), or maybe you know
-your preferred conventional dynamic language usually can be executed like another shell language, for instance http://groovy.codehaus.org/Running[Groovy],
-http://www.linuxjournal.com/content/python-scripts-replacement-bash-utility-scripts[Python], http://stackoverflow.com/questions/166347/how-do-i-use-ruby-for-shell-scripting[Ruby]
-or http://www.2ality.com/2011/12/nodejs-shell-scripting.html[JavaScript].
-
-But when you think Java like a new shell scripting language sure you say "it's impossible".
-
-No, it is possible, RelProxy includes a tool named *`jproxysh`* to make possible executing pure Java code like another shell scripting language.
-
-The principle is simple and is very similar to Groovy scripting, Groovy compiles on the fly Groovy code saving in memory the compiled bytecode, by this way developers
-think Groovy script is interpreted and is not, the same approach is applied to Java through RelProxy. In the case of RelProxy, bytecode can be optionally saved as .class
-files to avoid compiling on the fly every time the script is executed. When the JVM is able to load .class files instead of compiling, code execution maybe extremely faster
-than conventional scripting languages interpreted line by line from sources, this is why the affirmation of Java as the fastest scripting language of the world is accurate.
-
-Because pure Java is used and the standard compiler API, nothing prevents using Java scripting in the less verbose Java 8 (v1.8).
-
-
-=== Defining a Java based shell scripting file
-
-Let's see the first example (some background of UNIX shell is required):
-
-[source,java]
-.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();
-----
-
-The best way to think this script is like the content of the standard method `main` of a class with some invented name in the default package (no package), in fact,
-this is how it is managed internally by RelProxy.
-
-We could use `/bin/jproxysh` or `/usr/local/bin/jproxysh` but we are forced to install RelProxy in a concrete fixed place, by using `/usr/bin/env` the command `jproxysh`
-will be located using the current PATH.
-
-Save this file in a folder root of the dependent classes. The dependent class in this example is `JProxyShellExample`.
-
-The hierarchy is:
-
-++++
-
-++++
-
-
-{nbsp} +
-Yes, you are right, mentally add the .java extension to `example_java_shell` and you get the typical file hierarchy of a JavaSE program, in fact JProxy is ready to execute a conventional
-JavaSE program with no explicit compilation, this will be shown later.
-
-The first requisite is that `jproxysh` must be accessible by the environment variable `PATH`, anyway executing this script is not direct, it requires some previous configuration:
-
-* First of all the `JAVA_HOME` environment variable is required.
-* The `CLASSPATH` environment variable must locate the `relproxy-X.X.jar` file and other folders and jars required by your Java application, conventions are the same than a typical JavaSE program.
-* Optionally you may specify `JAVA_OPTS` to provide runtime options for the JVM.
-
-There are other _optional_ environment variables in this case RelProxy specific:
-
-* JPROXYSH_CACHE_CLASS_FOLDER : defines where to save the .class files resulting of compiling on the fly the scripting code, this folder is automatically added to the class path,
-so when the script is loaded the second time the .class files are used instead of source code according to the typical source-binary timestamp rules (if source code is more recent the
-class is ignored and replaced with a new file).
-* JPROXYSH_COMPILATION_OPTIONS : compilations passed to the JDK compiler, the format is the same as the command line `javac`.
-
-The following is an example of shell code (into a script file) to execute the previous `example_java_shell`, this example is included in RelProxy distribution:
-
-[source,sh]
-.ex_java_shell_launcher.sh
-----
-#!/bin/sh
-
-RELPROXY_JAR=relproxy-0.8.8.jar
-
-PROJECT=`dirname $0`/..
-
-# set PROJECT env as absolute path
-TMP_PWD=`pwd`
-cd $PROJECT
-PROJECT=`pwd`
-cd $TMP_PWD
-
-if [ -z "$JAVA_HOME" ]; then
- echo Missing JAVA_HOME environment variable, exiting...
- exit 1
-fi
-
-export PATH=$PATH:$PROJECT/bin
-export CLASSPATH=$PROJECT/lib/$RELPROXY_JAR
-export JAVA_OPTS="-client -Xmx100m"
-# Nothing really required in JAVA_OPTS, just to test
-
-export JPROXYSH_CACHE_CLASS_FOLDER="$PROJECT/tmp/java_shell_test_classes"
-export JPROXYSH_COMPILATION_OPTIONS="-source 1.6 -target 1.6"
-
-$PROJECT/cmd_examples/code/example_java_shell "HELLO " "WORLD!"
-----
-
-Because `example_java_shell` is a `jproxysh` based script, nothing prevents of being executed directly using `jproxysh`:
-
-[source,sh]
-----
-jproxysh $PROJECT/cmd_examples/code/example_java_shell "HELLO " "WORLD!"
-----
-
-
-
-=== Defining a complete Java class
-
-As you have seen in `example_java_shell` example, you can access to other Java "scripting" classes from the initial scripting file, this is really interesting when your scripts
-become too large and you need state (attributes) more methods and so on, that is, you need more classes.
-
-If you need your scripting code more structured, you have the option of defining a conventional class in the scripting main file.
-
-Take a look to this example also included in RelProxy distribution (slightly modified):
-
-[source,sh]
-.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();
- }
-}
-----
-
-`example_java_shell_complete_class` is a conventional class, you can add methods, attributes and so on, the only limitation is the name of the class, it must be the same as the
-container file (in this case the container file has not the .java extension).
-
-You can execute this script by the same ways we executed `example_java_shell`, directly or as a parameter of `jproxysh`.
-
-=== Scripting conventional JavaSE source code
-
-The differences between the `example_java_shell_complete_class` script and a conventional Java source file are just the extension (missing) and the hash bang to execute jproxysh.
-
-We can remove the hashbang and add the `.java` extension to the main scripting file, in this scenario the source code is the same as a conventional JavaSE application.
-
-Instead of compiling with `javac` and executing with `java` command, you just must execute it with `jproxysh`
-
-[source,sh]
-----
-jproxysh $PROJECT/cmd_examples/code/example_normal_class.java "HELLO " "WORLD!"
-----
-
-
-=== Executing a Java code snippet
-
-We have seen how much overcomplex can be our scripting files, what if you just need to execute one, or two or three sentences...
-You don't need to create a Java shell scripting file, you can write down your script as a parameter and execute. RelProxy through `jproxy` allows executing Java code snippets
-on the fly.
-
-The following is a shell script included in RelProxy distribution which executes a simple code snippet (the param `-c` indicates you are going to execute inline code):
-
-[source,sh]
-.ex_java_shell_snippet_launcher.sh
-----
-#!/bin/sh
-
-RELPROXY_JAR=relproxy-0.8.8.jar
-
-PROJECT=`dirname $0`/..
-
-# set PROJECT env as absolute path
-TMP_PWD=`pwd`
-cd $PROJECT
-PROJECT=`pwd`
-cd $TMP_PWD
-
-if [ -z "$JAVA_HOME" ]; then
- echo Missing JAVA_HOME environment variable, exiting...
- exit 1
-fi
-
-export PATH=$PATH:$PROJECT/bin
-export CLASSPATH=$PROJECT/lib/$RELPROXY_JAR
-export JAVA_OPTS="-client -Xmx100m"
-# Nothing really required in JAVA_OPTS, just to test
-
-export JPROXYSH_COMPILATION_OPTIONS="-source 1.6 -target 1.6"
-
-jproxysh -c 'System.out.print("This code snippet says: ");' \
- 'System.out.println("Hello World!!");'
-----
-
-You can execute a single code block (into a string parameter) or several blocks in several lines separated with "\", every block can contain several Java sentences.
-
-Alternatively you can execute a complete class with a standard `main` method, RelProxy detects when you are specifying a sentence block or a complete class, in this case because there
-is no file holding the code, the class name must be known by default and must be `_jproxyMainClass_`. For instance:
-
-[source,sh]
-----
-jproxysh -c 'public class _jproxyMainClass_ { ' \
- ' public static void main(String[] args) { ' \
- ' System.out.print("This code snippet says: ");' \
- ' System.out.println("Hello World!!");' \
- ' }' \
- '}'
-----
-
-
-
-=== The interactive Java shell
-
-When you need something more interactive, just like the Groovy shell, RelProxy provides a simple interactive shell.
-
-To launch the interactive shell define the required environment variables like the code snippet example and execute `jproxysh` with no parameters:
-
-[source,sh]
-----
-jproxysh
-----
-
-A message info is shown and a prompt is shown waiting for your commands and or code. Write `help` to know the shell options, if the text written is not recognized like a command
-it is interpreted as Java code and saved in a buffer to be executed when you want writing the 'exec' command.
-
-The interactive Java shell accepts a block of sentences or a complete class with a standard `main` method and name `_jproxyMainClass_`.
-
-=== How to use RelProxy shell scripting in Windows
-
-RelProxy does not provide a `jproxysh` version for Windows because you can easily build a mini-Linux/Unix in your Windows box with http://www.mingw.org/[MinGW/MSYS].
-
-Install MinGW/MSYS, you must be able to locate the shell launcher `msys.bat` in a folder like `C:\MinGW\msys\1.0\` (exact location may change according to your installation folder).
-
-Execute `msys.bat` and you will get a simple Linux shell environment, in this environment you can execute your typical Linux commands like `ls`, `ps`, `find` etc and of course
-launch the previous script files documented in this manual and included in RelProxy distribution.
-
-You can go to your required folder in MSYS with a `cd` command like this:
-
-[source,sh]
-----
-cd "C:\Program Files\MyProgram"
-----
-
-Or using a Unix format:
-
-[source,sh]
-----
-cd "/c/Program Files/MyProgram"
-----
-
-MSYS console is enough for most of purposes, if you can also install `mintty` using the MinGW GUI or command based installer, calling `mintty&` in MSYS opens an even more sophisticated
-Linux console. Mintty has some problem with some keyboard characters editing Java code in the RelProxy interactive console, back to basic MSYS console when necesssary.
-
-If you need to execute Linux shell scripts (for instance RelProxy based) from Windows without a Linux like interactive console, do something like this in your Windows script or console:
-
-[source,sh]
-----
-set PATH=C:\MinGW\msys\1.0\bin;%PATH%
-sh
-----
-
-Where `` can have Windows or Linux format (e.g. `/c/development/relproxy/cmd_examples/ex_java_shell_launcher.sh`).
-
-== Java Scripting API implementation
-
-RelProxy implements the official JSR-223 http://docs.oracle.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.html[Java Scripting API] as found
-in Java 1.6.
-
-The following Java code shows how to create the Java Scripting factory, get an engine instance and execute some code:
-
-[source,java]
-----
-// ...
-JProxyConfig jpConfig = JProxy.createJProxyConfig();
-jpConfig.setEnabled(true)
- .setRelProxyOnReloadListener(proxyListener)
- .setInputPath(inputPath)
- .setScanPeriod(scanPeriod)
- .setClassFolder(classFolder)
- .setCompilationOptions(compilationOptions)
- .setJProxyDiagnosticsListener(diagnosticsListener);
-
-JProxyScriptEngineFactory factory = JProxyScriptEngineFactory.create();
-
-ScriptEngineManager manager = new ScriptEngineManager();
-manager.registerEngineName("Java", factory);
-
-manager.getBindings().put("msg","HELLO GLOBAL WORLD!");
-
-ScriptEngine engine = (JProxyScriptEngine)manager.getEngineByName("Java");
-
-((JProxyScriptEngine)engine).init(jpConfig);
-
-Bindings bindings = engine.createBindings();
-bindings.put("msg","HELLO ENGINE SCOPE WORLD!");
-
-
-StringBuilder code = new StringBuilder();
-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("RETURNED: " + result);
-
-((JProxyScriptEngine)engine).stop(); // Necessary if scanPeriod > 0 was defined
-----
-
-
-As you can see initialization code is the same as in `JProxy` examples, returned `ScriptEngine` implements `JProxyScriptEngine`, this interface defines the same methods you are going to find in `JProxy`,
-the main difference between `JProxy` and `JProxyScriptEngine` (implementing `ScriptEngine`) is that `JProxy` use is based on static methods and `JProxyScriptEngine` in practice
-is a singleton. In theory you get a new `ScriptEngine` instance every time you call `manager.getEngineByName("Java")`, just call once, use the returned object as a singleton
-and you will get a similar environment to `JProxy` plus the capability of executing code snipets, otherwise concurrent conflicting can happen when competing several `ScriptEngine`
-objects (unless configured folders are different).
-
-Inside the `eval` method, compilation phase is thread safe but not code execution, you can use several threads to call `eval` and execute concurrent lengthy tasks without
-execution blocking.
-
-The last line:
-
-[source,java]
-----
-((JProxyScriptEngine)engine).stop(); // Necessary if scanPeriod > 0 was defined
-----
-
-The interface `JProxyScriptEngine` defines the same methods you are going to find in `JProxy`, for instance
-the `stop()` method, this method is necessary whether you define a `scanPeriod` and you want to dispose the `ScriptEngine` (otherwise the `ScriptEngine` is looking for
-source changes forever), you can also register reloadable singletons calling `JProxyScriptEngine.create(...)` like in JProxy`.
-
-
-The scripting code can be the content of a `main` method with this signature:
-
-[source,java]
-----
-public static Object main(javax.script.ScriptEngine engine,javax.script.ScriptContext context)
-----
-
-Or optionally you can define a complete Java class containing the previous `main` method and name `_jproxyMainClass_`, for instance:
-
-[source,java]
-----
-public class _jproxyMainClass_ {
- public static Object main(javax.script.ScriptEngine engine,javax.script.ScriptContext context) {
- javax.script.Bindings bindings = context.getBindings(javax.script.ScriptContext.ENGINE_SCOPE);
- // ...
- }
-}
-----
-
-You can directly call the `JProxyScriptEngineFactory.getScriptEngine()` method without registering on a `ScriptEngineManager`, in this case avoid calling
-`ServiceContext.getBindings(javax.script.ScriptContext.GLOBAL_SCOPE)` because the default global scope `Bindings` object is not defined. In fact the method
-`ScriptEngineManager.getEngineByName(String)` calls `JProxyScriptEngineFactory.getScriptEngine()` and may return null if the `JProxyScriptEngineFactory.getScriptEngine()`
-method throws an exception for instance when some configuration data is wrong, because there is no log info of this exception you have no way to know what is happening, in
-this case directly call `JProxyScriptEngineFactory.getScriptEngine()` to know what is happening.
-
-Example:
-
-[source,java]
-----
-// ...
-
-JProxyScriptEngineFactory factory = JProxyScriptEngineFactory.create();
-
-ScriptEngine engine = factory.getScriptEngine();
-
-((JProxyScriptEngine)engine).init(jpConfig);
-
-Bindings bindings = engine.createBindings();
-bindings.put("msg","HELLO ENGINE SCOPE WORLD!");
-
-StringBuilder code = new StringBuilder();
-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( " example.javashellex.JProxyShellExample.exec(engine); \n");
-code.append( " return \"SUCCESS\";");
-
-String result = (String)engine.eval( code.toString() , bindings);
-System.out.println("RETURNED: " + result);
-
-((JProxyScriptEngine)engine).stop(); // Necessary if scanPeriod > 0 was defined
-----
-
-If you need two or more different configurations, create two or more `JProxyScriptEngine` with different configurations.
-
-
-
-== Embedding RelProxy Java in your Java framework to provide hot reload
-
-RelProxy use requires some RelProxy explicit code to provide hot class reloading. If you are a developer of a Java framework, or an autonomous Java service
-module in general, you can built-in RelProxy Java in your framework to transparently provide code autoreload to end user code using your framework without
-explicit use of the RelProxy API in your end user code beyond some required configuration.
-
-There are two kind of APIs for using the Java part of RelProxy:
-
-. JProxy class and related: mainly static methods
-. Java Scripting API: based on interfaces
-
-The second option is preferred to embed RelProxy Java in your Java framework because it is based on interfaces, no public class of RelProxy is needed to expose
-in your API, because bootstrap can be executed into your framework. We are going to use the simplified version of the API using `JProxyScriptEngineFactory.create()`.
-
-
-The `JProxyScriptEngine` has been designed to provided the same functionality than `JProxy`, that is, the same methods, but in this case using a pure interface.
-
-A simple example is the best way to show how to embed RelProxy, this example, RelProxyBuiltin (project relproxy_builtin_ex), is included in the RelProxy Examples repository.
-It defines two listeners to be implemented and registered by end user code, one listener is to show the options and the other to execute the corresponding selected action.
-
-This mini framework and use example is developed using NetBeans and Maven.
-
-There are two packages:
-
-. `com.innowhere.relproxy_builtin_ex` : the mini framework. The subpackage `com.innowhere.relproxy_builtin_ex.impl` contains the only non-public class of the framework.
-. `com.innowhere.relproxy_builtin_ex_main` : a simple use example.
-
-The mini framework (public class and interfaces):
-
-[source,java]
-.RelProxyBuiltinRoot.java
-----
-package com.innowhere.relproxy_builtin_ex;
-
-import com.innowhere.relproxy_builtin_ex.impl.RelProxyBuiltinImpl;
-
-public class RelProxyBuiltinRoot
-{
- private final static RelProxyBuiltinImpl SINGLETON = new RelProxyBuiltinImpl();
-
- public static RelProxyBuiltin get()
- {
- return SINGLETON;
- }
-}
-----
-
-[source,java]
-.RelProxyBuiltin.java
-----
-package com.innowhere.relproxy_builtin_ex;
-
-import com.innowhere.relproxy.jproxy.JProxyScriptEngine;
-import java.io.InputStream;
-import java.io.PrintStream;
-
-public interface RelProxyBuiltin
-{
- public JProxyScriptEngine getJProxyScriptEngine();
-
- public void addOutputListener(OutputListener listener);
- public void removeOutputListener(OutputListener listener);
- public int getOutputListenerCount();
-
- public void addCommandListener(CommandListener listener);
- public void removeCommandListener(CommandListener listener);
- public int getCommandListenerCount();
-
- public void runLoop(InputStream in,PrintStream out);
-}
-----
-
-[source,java]
-.OutputListener.java
-----
-package com.innowhere.relproxy_builtin_ex;
-
-import java.io.PrintStream;
-
-public interface OutputListener
-{
- public void write(PrintStream out);
-}
-----
-
-[source,java]
-.CommandListener.java
-----
-package com.innowhere.relproxy_builtin_ex;
-
-import java.io.PrintStream;
-
-public interface CommandListener
-{
- public void execute(String command,String input,PrintStream out);
-}
-----
-
-Now the implementation details, this class shows how simple is to built-in RelProxy:
-
-[source,java]
-.RelProxyBuiltinImpl.java
-----
-package com.innowhere.relproxy_builtin_ex.impl;
-
-import com.innowhere.relproxy.jproxy.JProxyScriptEngine;
-import com.innowhere.relproxy.jproxy.JProxyScriptEngineFactory;
-import com.innowhere.relproxy_builtin_ex.CommandListener;
-import com.innowhere.relproxy_builtin_ex.OutputListener;
-import com.innowhere.relproxy_builtin_ex.RelProxyBuiltin;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.util.LinkedHashSet;
-import java.util.Scanner;
-
-public class RelProxyBuiltinImpl implements RelProxyBuiltin
-{
- protected JProxyScriptEngine jProxyEngine = null;
- protected LinkedHashSet outListeners = new LinkedHashSet();
- protected LinkedHashSet commandListeners = new LinkedHashSet();
-
- @Override
- public JProxyScriptEngine getJProxyScriptEngine()
- {
- if (jProxyEngine == null) jProxyEngine = (JProxyScriptEngine)JProxyScriptEngineFactory.create().getScriptEngine();
- return jProxyEngine;
- }
-
- public JProxyScriptEngine getJProxyScriptEngineIfConfigured()
- {
- if (jProxyEngine == null || !jProxyEngine.isEnabled())
- return null;
- return jProxyEngine;
- }
-
- @Override
- public void addOutputListener(OutputListener listener)
- {
- JProxyScriptEngine jProxy = getJProxyScriptEngineIfConfigured();
- if (jProxy != null)
- {
- listener = jProxy.create(listener,OutputListener.class);
- }
- outListeners.add(listener);
- }
-
- @Override
- public void removeOutputListener(OutputListener listener)
- {
- JProxyScriptEngine jProxy = getJProxyScriptEngineIfConfigured();
- if (jProxy != null)
- {
- listener = jProxy.create(listener,OutputListener.class);
- }
- outListeners.remove(listener);
- }
-
- @Override
- public int getOutputListenerCount()
- {
- return outListeners.size();
- }
-
- @Override
- public void addCommandListener(CommandListener listener)
- {
- JProxyScriptEngine jProxy = getJProxyScriptEngineIfConfigured();
- if (jProxy != null)
- {
- listener = jProxy.create(listener,CommandListener.class);
- }
- commandListeners.add(listener);
- }
-
- @Override
- public void removeCommandListener(CommandListener listener)
- {
- JProxyScriptEngine jProxy = getJProxyScriptEngineIfConfigured();
- if (jProxy != null)
- {
- listener = jProxy.create(listener,CommandListener.class);
- }
- commandListeners.remove(listener);
- }
-
- @Override
- public int getCommandListenerCount()
- {
- return commandListeners.size();
- }
-
- @Override
- public void runLoop(InputStream in,PrintStream out)
- {
- Scanner scanner = new Scanner(in);
-
- while(true)
- {
- out.print("Enter phrase:");
-
- String input = scanner.nextLine();
-
- out.println("Command list:");
-
- for(OutputListener listener : outListeners)
- listener.write(out);
-
- out.print("Enter command (or quit):");
- String command = scanner.nextLine();
- if ("quit".equals(command))
- break;
-
- for(CommandListener listener : commandListeners)
- listener.execute(command,input,out);
- }
- }
-}
-----
-
-These three methods are enough to explain how to bootstrap RelProxy Java engine and how easy is to instrument listener registering hot reloadable:
-
-[source,java]
-.RelProxyBuiltinImpl.java (partial)
-----
- @Override
- public JProxyScriptEngine getJProxyScriptEngine()
- {
- if (jProxyEngine == null) jProxyEngine = (JProxyScriptEngine)JProxyScriptEngineFactory.create().getScriptEngine();
- return jProxyEngine;
- }
-
- public JProxyScriptEngine getJProxyScriptEngineIfConfigured()
- {
- if (jProxyEngine == null || !jProxyEngine.isEnabled())
- return null;
- return jProxyEngine;
- }
-
- @Override
- public void addOutputListener(OutputListener listener)
- {
- JProxyScriptEngine jProxy = getJProxyScriptEngineIfConfigured();
- if (jProxy != null)
- {
- listener = jProxy.create(listener,OutputListener.class);
- }
- outListeners.add(listener);
- }
-----
-
-The public method `RelProxyBuiltin.getJProxyScriptEngine()` must be called in starting time to configure RelProxy. If RelProxy is not configured and enabled there is no performance penalty.
-
-Remember that the proxy object returned by `create(...)` method correctly calls the method `hashCode()` and `equals(Object)` in the internal true listener object for
-identity purposes required by the listener collection/registry.
-
-
-This is the example code of this console based program (names are inspired on JUnit but is not really a JUnit test example):
-
-[source,java]
-.Main.java
-----
-package com.innowhere.relproxy_builtin_ex_main;
-
-import com.innowhere.relproxy.RelProxyOnReloadListener;
-import com.innowhere.relproxy.jproxy.JProxy;
-import com.innowhere.relproxy.jproxy.JProxyCompilerListener;
-import com.innowhere.relproxy.jproxy.JProxyConfig;
-import com.innowhere.relproxy.jproxy.JProxyDiagnosticsListener;
-import com.innowhere.relproxy.jproxy.JProxyInputSourceFileExcludedListener;
-import com.innowhere.relproxy.jproxy.JProxyScriptEngine;
-import com.innowhere.relproxy_builtin_ex.CommandListener;
-import com.innowhere.relproxy_builtin_ex.RelProxyBuiltin;
-import com.innowhere.relproxy_builtin_ex.RelProxyBuiltinRoot;
-import java.io.File;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.util.Arrays;
-import java.util.List;
-import javax.tools.Diagnostic;
-import javax.tools.DiagnosticCollector;
-import javax.tools.JavaFileObject;
-
-public class Main
-{
- public static void main(String[] args) throws Exception
- {
- new Main();
- }
-
- public Main()
- {
- // Note: NetBeans Console window works bad (no input) with Maven Test tasks http://stackoverflow.com/questions/3035351/broken-console-in-maven-project-using-netbeans
- // this is why is not a really JUnit test.
- setUp();
- try
- {
- mainTest();
- }
- finally
- {
- tearDown();
- }
- System.exit(0);
- }
-
- public void setUp()
- {
- URL res = this.getClass().getResource("/"); // .../target/classes/
-
- // Use example of RelProxy in development time:
-
- String inputPath = res.getFile() + "/../../src/main/java/";
-
- if (new File(inputPath).exists())
- {
- System.out.println("RelProxy to be enabled, development mode detected");
- }
- else
- {
- System.out.println("RelProxy disabled, production mode detected");
- return;
- }
-
-
- JProxyInputSourceFileExcludedListener excludedListener = new JProxyInputSourceFileExcludedListener()
- {
- @Override
- public boolean isExcluded(File file, File rootFolderOfSources)
- {
- String absPath = file.getAbsolutePath();
-
- if (file.isDirectory())
- {
- return absPath.endsWith(File.separatorChar + "relproxy_builtin_ex");
- }
- else
- {
- return absPath.endsWith(File.separatorChar + Main.class.getSimpleName() + ".java");
- }
- }
- };
-
- String classFolder = null; // Optional
- Iterable compilationOptions = Arrays.asList(new String[]{"-source","1.6","-target","1.6"});
- long scanPeriod = 1000;
-
- 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);
- }
- };
-
- 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);
- }
- };
-
- JProxyDiagnosticsListener diagnosticsListener = new JProxyDiagnosticsListener()
- {
- @Override
- public void onDiagnostics(DiagnosticCollector diagnostics)
- {
- List> 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++;
- }
- }
- };
-
- RelProxyBuiltin rpbRoot = RelProxyBuiltinRoot.get();
- JProxyScriptEngine engine = rpbRoot.getJProxyScriptEngine();
-
- JProxyConfig jpConfig = JProxy.createJProxyConfig();
- jpConfig.setEnabled(true)
- .setRelProxyOnReloadListener(proxyListener)
- .setInputPath(inputPath)
- .setJProxyInputSourceFileExcludedListener(excludedListener)
- .setScanPeriod(scanPeriod)
- .setClassFolder(classFolder)
- .setCompilationOptions(compilationOptions)
- .setJProxyCompilerListener(compilerListener)
- .setJProxyDiagnosticsListener(diagnosticsListener);
-
- engine.init(jpConfig);
-
- System.out.println("RelProxy running");
- }
-
- public void tearDown()
- {
- RelProxyBuiltin rpbRoot = RelProxyBuiltinRoot.get();
- JProxyScriptEngine engine = rpbRoot.getJProxyScriptEngine();
- engine.stop();
-
- System.out.println("RelProxy stopped");
- }
-
- public void mainTest()
- {
- RelProxyBuiltin rpbRoot = RelProxyBuiltinRoot.get();
-
- TestListener listener = new TestListener();
-
- rpbRoot.addOutputListener(listener);
- assertTrue(rpbRoot.getOutputListenerCount() == 1);
- rpbRoot.removeOutputListener(listener);
- assertTrue(rpbRoot.getOutputListenerCount() == 0);
-
- rpbRoot.addOutputListener(listener);
-
-
- CommandListener commandListener = listener.getCommandListener();
-
- rpbRoot.addCommandListener(commandListener);
- assertTrue(rpbRoot.getCommandListenerCount() == 1);
- rpbRoot.removeCommandListener(commandListener);
- assertTrue(rpbRoot.getCommandListenerCount() == 0);
-
- rpbRoot.addCommandListener(commandListener);
-
- rpbRoot.runLoop(System.in,System.out);
- }
-
-
- private static void assertTrue(boolean res)
- {
- if (!res) throw new RuntimeException("Unexpected Error");
- }
-}
-
-----
-
-Take a look to this piece of code:
-
-[source,java]
-.Main.java (partial)
-----
- URL res = this.getClass().getResource("/"); // .../target/classes/
-
- // Use example of RelProxy in development time:
-
- String inputPath = res.getFile() + "/../../src/main/java/";
-
- if (new File(inputPath).exists())
- {
- System.out.println("RelProxy to be enabled, development mode detected");
- }
- else
- {
- System.out.println("RelProxy disabled, production mode detected");
- return;
- }
-
- JProxyInputSourceFileExcludedListener excludedListener = new JProxyInputSourceFileExcludedListener()
- {
- @Override
- public boolean isExcluded(File file, File rootFolderOfSources)
- {
- String absPath = file.getAbsolutePath();
-
- if (file.isDirectory())
- {
- return absPath.endsWith(File.separatorChar + "relproxy_builtin_ex");
- }
- else
- {
- return absPath.endsWith(File.separatorChar + Main.class.getSimpleName() + ".java");
- }
- }
- };
-----
-
-We get and later register the root folder of the source code of our application, this code "may be" reloadable.
-
-We need to exclude the source code of the framework because is not obviously end user code (not reloadable), and the `Main.java` file containing
-the test code, this class is not reloadable, only the class `TestListener.java` (in the same folder than Main.java) will be (and must be) reloadable.
-We could simplify this `isExcluded` method just excluding anything different to the file `TestListener.java`, but excluding whole folders is recommended to
-speed the traversing of the source code file tree because otherwise all not reloadable files, into not reloadable folders, are checked.
-
-Finally the class `TestListener.java` containing both listeners, the `CommandListener` implemented is forced to be an anonymous inner class just for demonstrative purposes:
-
-[source,java]
-.TestListener.java
-----
-package com.innowhere.relproxy_builtin_ex_main;
-
-import com.innowhere.relproxy_builtin_ex.CommandListener;
-import com.innowhere.relproxy_builtin_ex.OutputListener;
-import java.io.PrintStream;
-
-public class TestListener implements OutputListener
-{
- @Override
- public void write(PrintStream out)
- {
- out.println("uppercase");
- out.println("lowercase");
- }
-
- public CommandListener getCommandListener()
- {
- return new CommandListener()
- {
- @Override
- public void execute(String command,String text,PrintStream out)
- {
- if ("uppercase".equals(command))
- out.println(text.toUpperCase());
- else if ("lowercase".equals(command))
- out.println(text.toLowerCase());
- else
- out.println("Unknown command:" + command);
- }
- };
- }
-}
-
-----
-
-Execute the Main class and try the predefined options. To check if RelProxy is working fine try to add a new option "same" without stopping the program:
-
-[source,java]
-----
-
- @Override
- public void write(PrintStream out)
- {
- out.println("uppercase");
- out.println("lowercase");
-
- out.println("same"); // NEW
- }
-
- public CommandListener getCommandListener()
- {
- return new CommandListener()
- {
- @Override
- public void execute(String command,String text,PrintStream out)
- {
- if ("uppercase".equals(command))
- out.println(text.toUpperCase());
- else if ("lowercase".equals(command))
- out.println(text.toLowerCase());
-
- else if ("same".equals(command)) // NEW
- out.println(text); // NEW
-
- else
- out.println("Unknown command:" + command);
- }
- };
- }
-}
-
-----
-
-The next phrase to process includes now the "same" action with no need of stopping the console application.
-
-Note: use RelProxy 0.8.7 or upper, this release adds an improvement when embedding by this way.
-
diff --git a/relproxy/src/main/cmd_examples/README.txt b/relproxy/src/main/cmd_examples/README.txt
deleted file mode 100644
index 14c3ec3..0000000
--- a/relproxy/src/main/cmd_examples/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-
-These files cannot be executed here, they will be copied to the distribution files able to be executed as examples of the final distribution form of RelProxy.
diff --git a/relproxy/src/main/cmd_examples/ex_java_shell_interactive_launcher.sh b/relproxy/src/main/cmd_examples/ex_java_shell_interactive_launcher.sh
deleted file mode 100644
index d3231e1..0000000
--- a/relproxy/src/main/cmd_examples/ex_java_shell_interactive_launcher.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-
-RELPROXY_JAR=relproxy-0.8.8.jar
-
-PROJECT=`dirname $0`/..
-
-# set PROJECT env as absolute path
-TMP_PWD=`pwd`
-cd $PROJECT
-PROJECT=`pwd`
-cd $TMP_PWD
-
-
-if [ -z "$JAVA_HOME" ]; then
- echo Missing JAVA_HOME environment variable, exiting...
- exit 1
-fi
-
-export PATH=$PATH:$PROJECT/bin
-export CLASSPATH=$PROJECT/lib/$RELPROXY_JAR
-export JAVA_OPTS="-client -Xmx100m"
-# Nothing really required in JAVA_OPTS, just to test
-
-export JPROXYSH_COMPILATION_OPTIONS="-source 1.6 -target 1.6"
-
-jproxysh
-
-
diff --git a/relproxy/src/main/cmd_examples/ex_java_shell_launcher.sh b/relproxy/src/main/cmd_examples/ex_java_shell_launcher.sh
deleted file mode 100644
index a3b282c..0000000
--- a/relproxy/src/main/cmd_examples/ex_java_shell_launcher.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/sh
-
-RELPROXY_JAR=relproxy-0.8.8.jar
-
-PROJECT=`dirname $0`/..
-
-# set PROJECT env as absolute path
-TMP_PWD=`pwd`
-cd $PROJECT
-PROJECT=`pwd`
-cd $TMP_PWD
-
-if [ -z "$JAVA_HOME" ]; then
- echo Missing JAVA_HOME environment variable, exiting...
- exit 1
-fi
-
-export PATH=$PATH:$PROJECT/bin
-export CLASSPATH=$PROJECT/lib/$RELPROXY_JAR
-export JAVA_OPTS="-client -Xmx100m"
-# Nothing really required in JAVA_OPTS, just to test
-
-export JPROXYSH_CACHE_CLASS_FOLDER="$PROJECT/tmp/java_shell_test_classes"
-export JPROXYSH_COMPILATION_OPTIONS="-source 1.6 -target 1.6"
-
-$PROJECT/cmd_examples/code/example_java_shell "HELLO " "WORLD!"
diff --git a/relproxy/src/main/cmd_examples/ex_java_shell_launcher_2.sh b/relproxy/src/main/cmd_examples/ex_java_shell_launcher_2.sh
deleted file mode 100644
index 4207ec9..0000000
--- a/relproxy/src/main/cmd_examples/ex_java_shell_launcher_2.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/sh
-
-RELPROXY_JAR=relproxy-0.8.8.jar
-
-PROJECT=`dirname $0`/..
-
-# set PROJECT env as absolute path
-TMP_PWD=`pwd`
-cd $PROJECT
-PROJECT=`pwd`
-cd $TMP_PWD
-
-if [ -z "$JAVA_HOME" ]; then
- echo Missing JAVA_HOME environment variable, exiting...
- exit 1
-fi
-
-export PATH=$PATH:$PROJECT/bin
-export CLASSPATH=$PROJECT/lib/$RELPROXY_JAR
-export JAVA_OPTS="-client -Xmx100m"
-# Nothing really required in JAVA_OPTS, just to test
-
-export JPROXYSH_CACHE_CLASS_FOLDER="$PROJECT/tmp/java_shell_test_classes"
-export JPROXYSH_COMPILATION_OPTIONS="-source 1.6 -target 1.6"
-
-jproxysh $PROJECT/cmd_examples/code/example_java_shell "HELLO " "WORLD!"
diff --git a/relproxy/src/main/cmd_examples/ex_java_shell_launcher_complete_class.sh b/relproxy/src/main/cmd_examples/ex_java_shell_launcher_complete_class.sh
deleted file mode 100644
index 6c7e2f6..0000000
--- a/relproxy/src/main/cmd_examples/ex_java_shell_launcher_complete_class.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/sh
-
-RELPROXY_JAR=relproxy-0.8.8.jar
-
-PROJECT=`dirname $0`/..
-
-# set PROJECT env as absolute path
-TMP_PWD=`pwd`
-cd $PROJECT
-PROJECT=`pwd`
-cd $TMP_PWD
-
-if [ -z "$JAVA_HOME" ]; then
- echo Missing JAVA_HOME environment variable, exiting...
- exit 1
-fi
-
-export PATH=$PATH:$PROJECT/bin
-export CLASSPATH=$PROJECT/lib/$RELPROXY_JAR
-export JAVA_OPTS="-client -Xmx100m"
-# Nothing really required in JAVA_OPTS, just to test
-
-export JPROXYSH_CACHE_CLASS_FOLDER="$PROJECT/tmp/java_shell_test_classes"
-export JPROXYSH_COMPILATION_OPTIONS="-source 1.6 -target 1.6"
-
-$PROJECT/cmd_examples/code/example_java_shell_complete_class "HELLO " "WORLD!"
diff --git a/relproxy/src/main/cmd_examples/ex_java_shell_launcher_complete_class_2.sh b/relproxy/src/main/cmd_examples/ex_java_shell_launcher_complete_class_2.sh
deleted file mode 100644
index 0e832ed..0000000
--- a/relproxy/src/main/cmd_examples/ex_java_shell_launcher_complete_class_2.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/sh
-
-RELPROXY_JAR=relproxy-0.8.8.jar
-
-PROJECT=`dirname $0`/..
-
-# set PROJECT env as absolute path
-TMP_PWD=`pwd`
-cd $PROJECT
-PROJECT=`pwd`
-cd $TMP_PWD
-
-if [ -z "$JAVA_HOME" ]; then
- echo Missing JAVA_HOME environment variable, exiting...
- exit 1
-fi
-
-export PATH=$PATH:$PROJECT/bin
-export CLASSPATH=$PROJECT/lib/$RELPROXY_JAR
-export JAVA_OPTS="-client -Xmx100m"
-# Nothing really required in JAVA_OPTS, just to test
-
-export JPROXYSH_CACHE_CLASS_FOLDER="$PROJECT/tmp/java_shell_test_classes"
-export JPROXYSH_COMPILATION_OPTIONS="-source 1.6 -target 1.6"
-
-jproxysh $PROJECT/cmd_examples/code/example_java_shell_complete_class "HELLO " "WORLD!"
diff --git a/relproxy/src/main/cmd_examples/ex_java_shell_launcher_normal_class.sh b/relproxy/src/main/cmd_examples/ex_java_shell_launcher_normal_class.sh
deleted file mode 100644
index 819b73e..0000000
--- a/relproxy/src/main/cmd_examples/ex_java_shell_launcher_normal_class.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/sh
-
-RELPROXY_JAR=relproxy-0.8.8.jar
-
-PROJECT=`dirname $0`/..
-
-# set PROJECT env as absolute path
-TMP_PWD=`pwd`
-cd $PROJECT
-PROJECT=`pwd`
-cd $TMP_PWD
-
-if [ -z "$JAVA_HOME" ]; then
- echo Missing JAVA_HOME environment variable, exiting...
- exit 1
-fi
-
-export PATH=$PATH:$PROJECT/bin
-export CLASSPATH=$PROJECT/lib/$RELPROXY_JAR
-export JAVA_OPTS="-client -Xmx100m"
-# Nothing really required in JAVA_OPTS, just to test
-
-export JPROXYSH_CACHE_CLASS_FOLDER="$PROJECT/tmp/java_shell_test_classes"
-export JPROXYSH_COMPILATION_OPTIONS="-source 1.6 -target 1.6"
-
-jproxysh $PROJECT/cmd_examples/code/example_normal_class.java "HELLO " "WORLD!"
diff --git a/relproxy/src/main/cmd_examples/ex_java_shell_snippet_launcher.sh b/relproxy/src/main/cmd_examples/ex_java_shell_snippet_launcher.sh
deleted file mode 100644
index 4d64334..0000000
--- a/relproxy/src/main/cmd_examples/ex_java_shell_snippet_launcher.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/sh
-
-RELPROXY_JAR=relproxy-0.8.8.jar
-
-PROJECT=`dirname $0`/..
-
-# set PROJECT env as absolute path
-TMP_PWD=`pwd`
-cd $PROJECT
-PROJECT=`pwd`
-cd $TMP_PWD
-
-if [ -z "$JAVA_HOME" ]; then
- echo Missing JAVA_HOME environment variable, exiting...
- exit 1
-fi
-
-export PATH=$PATH:$PROJECT/bin
-export CLASSPATH=$PROJECT/lib/$RELPROXY_JAR
-export JAVA_OPTS="-client -Xmx100m"
-# Nothing really required in JAVA_OPTS, just to test
-
-export JPROXYSH_COMPILATION_OPTIONS="-source 1.6 -target 1.6"
-
-jproxysh -c 'System.out.print("This code snippet says: ");' \
- 'System.out.println("Hello World!!");'
-
diff --git a/relproxy/src/main/cmd_examples/ex_java_shell_snippet_launcher_complete_class.sh b/relproxy/src/main/cmd_examples/ex_java_shell_snippet_launcher_complete_class.sh
deleted file mode 100644
index 5940699..0000000
--- a/relproxy/src/main/cmd_examples/ex_java_shell_snippet_launcher_complete_class.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/sh
-
-RELPROXY_JAR=relproxy-0.8.8.jar
-
-PROJECT=`dirname $0`/..
-
-# set PROJECT env as absolute path
-TMP_PWD=`pwd`
-cd $PROJECT
-PROJECT=`pwd`
-cd $TMP_PWD
-
-if [ -z "$JAVA_HOME" ]; then
- echo Missing JAVA_HOME environment variable, exiting...
- exit 1
-fi
-
-export PATH=$PATH:$PROJECT/bin
-export CLASSPATH=$PROJECT/lib/$RELPROXY_JAR
-export JAVA_OPTS="-client -Xmx100m"
-# Nothing really required in JAVA_OPTS, just to test
-
-export JPROXYSH_COMPILATION_OPTIONS="-source 1.6 -target 1.6"
-
-jproxysh -c 'public class _jproxyMainClass_ { ' \
- ' public static void main(String[] args) { ' \
- ' System.out.print("This code snippet says: ");' \
- ' System.out.println("Hello World!!");' \
- ' }' \
- '}'
diff --git a/relproxy/src/main/cmd_examples/fixesforunix.sh b/relproxy/src/main/cmd_examples/fixesforunix.sh
deleted file mode 100644
index e146ea3..0000000
--- a/relproxy/src/main/cmd_examples/fixesforunix.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-
-PROJECT=`dirname $0`/..
-
-# set PROJECT env as absolute path
-TMP_PWD=`pwd`
-cd $PROJECT
-PROJECT=`pwd`
-cd $TMP_PWD
-
-chmod +x $PROJECT/cmd_examples/*.sh
-
-chmod +x $PROJECT/cmd_examples/code/example_java_shell
-chmod +x $PROJECT/cmd_examples/code/example_java_shell_complete_class
-
-chmod +x $PROJECT/bin/jproxysh
diff --git a/relproxy/src/main/java/com/innowhere/relproxy/RelProxy.java b/relproxy/src/main/java/com/innowhere/relproxy/RelProxy.java
deleted file mode 100644
index 8341873..0000000
--- a/relproxy/src/main/java/com/innowhere/relproxy/RelProxy.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.innowhere.relproxy;
-
-/**
- * Is the root of RelProxy
- *
- * @author Jose Maria Arranz Santamaria
- */
-public class RelProxy
-{
- /**
- * Returns the version of this RelProxy library.
- *
- * @return the version of the library.
- */
- public static String getVersion()
- {
- return "0.8.8";
- }
-}
diff --git a/relproxy/src/main/java/com/innowhere/relproxy/RelProxyException.java b/relproxy/src/main/java/com/innowhere/relproxy/RelProxyException.java
deleted file mode 100644
index f8e4666..0000000
--- a/relproxy/src/main/java/com/innowhere/relproxy/RelProxyException.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.innowhere.relproxy;
-
-/**
- * Internal checked exceptions thrown by RelProxy and library specific errors are wrapped into this exception class.
- *
- * @author Jose Maria Arranz Santamaria
- */
-public class RelProxyException extends RuntimeException
-{
- /**
- * Constructs a new exception with the specified message and cause.
- *
- *
Parameters are passed to the super constructor.
- *
- * @param message the detail message
- * @param cause the cause
- */
- public RelProxyException(String message, Throwable cause)
- {
- super(message, cause);
- }
-
- /**
- * Constructs a new exception with the specified message.
- *
- *
Parameter is passed to the super constructor.
- *
- * @param message the detail message
- */
- public RelProxyException(String message)
- {
- super(message);
- }
-
- /**
- * Constructs a new exception with the specified cause.
- *
- *
Parameter is passed to the super constructor.
- *
- * @param cause the cause
- */
- public RelProxyException(Throwable cause)
- {
- super(cause);
- }
-}
diff --git a/relproxy/src/main/java/com/innowhere/relproxy/RelProxyOnReloadListener.java b/relproxy/src/main/java/com/innowhere/relproxy/RelProxyOnReloadListener.java
deleted file mode 100644
index 2fc287d..0000000
--- a/relproxy/src/main/java/com/innowhere/relproxy/RelProxyOnReloadListener.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.innowhere.relproxy;
-
-import java.lang.reflect.Method;
-
-/**
- * Is the interface needed to register a class reload listener.
- *
- *
An object implementing this interface can optionally be registered on RelProxy to listen when the method of a proxy object has been called
- * and the class of the original object associated has been reloaded (and a new "original" object based on the new class was created to replace it).
- *
- *
- *
- * @see com.innowhere.relproxy.jproxy.JProxyConfig#setRelProxyOnReloadListener(com.innowhere.relproxy.RelProxyOnReloadListener)
- * @see com.innowhere.relproxy.gproxy.GProxyConfig#setRelProxyOnReloadListener(com.innowhere.relproxy.RelProxyOnReloadListener)
- * @author Jose Maria Arranz Santamaria
- */
-public interface RelProxyOnReloadListener
-{
- /**
- * Called when some source code change has happened and a new class has been compiled and reloaded.
- *
- * @param objOld the old object before class reload.
- * @param objNew the new object based on the new class loaded by the new class loader.
- * @param proxy the proxy object created by {@link java.lang.reflect.Proxy} being used.
- * @param method the method being called through the proxy object.
- * @param args the parameters being used in the method call.
- */
- public void onReload(Object objOld,Object objNew,Object proxy, Method method, Object[] args);
-}
diff --git a/relproxy/src/main/java/com/innowhere/relproxy/gproxy/GProxy.java b/relproxy/src/main/java/com/innowhere/relproxy/gproxy/GProxy.java
deleted file mode 100644
index 1ec80b2..0000000
--- a/relproxy/src/main/java/com/innowhere/relproxy/gproxy/GProxy.java
+++ /dev/null
@@ -1,68 +0,0 @@
-
-package com.innowhere.relproxy.gproxy;
-
-import com.innowhere.relproxy.impl.gproxy.GProxyConfigImpl;
-import com.innowhere.relproxy.impl.gproxy.GProxyDefaultImpl;
-
-/**
- * Is the class to create Java proxy objects based on Groovy objects and keep track of Groovy source code changes reloading Groovy classes when detected.
- *
- * @author Jose Maria Arranz Santamaria
- */
-public class GProxy
-{
- /**
- * Creates a {@link GProxyConfig} object to be used to configure GProxy.
- *
- * @return a new configuration object.
- * @see #init(GProxyConfig)
- */
- public static GProxyConfig createGProxyConfig()
- {
- return GProxyDefaultImpl.createGProxyConfig();
- }
-
- /**
- * Initializes GProxy with the provided configuration object.
- *
- * @param config
- */
- public static void init(GProxyConfig config)
- {
- GProxyDefaultImpl.initStatic((GProxyConfigImpl)config);
- }
-
- /**
- * Creates a proxy object using java.lang.reflect.Proxy based on the provided Groovy object and the class of the implemented Java interface.
- *
- *
This method is a simplification for a single interface (the most common case) of {@link #create(Object,Class>[])} .
- *
- * @param the interface implemented by the original object and proxy object returned.
- * @param obj the original object to proxy.
- * @param clasz the class of the interface implemented by the original object and proxy object returned.
- * @return the java.lang.reflect.Proxy object associated or the original object when GProxy is disabled.
- */
- public static T create(T obj,Class clasz)
- {
- return GProxyDefaultImpl.createStatic(obj, clasz);
- }
-
- /**
- * Creates a proxy object using java.lang.reflect.Proxy based on the provided Groovy object and the classes of the implemented Java interfaces.
- *
- *
If GProxy has been configured and is enabled this method returns a java.lang.reflect.Proxy object implementing instead of
- * the original object provided. Methods called in proxy object are received by GProxy and forwarded to the original object, if source code
- * managed by GProxy has been changed, the class of the original object is reloaded based on the new source and the original object
- * is recreated with the new class and fields are re-set in the new object, then the method is called on the new original object.
- *
- *
If GProxy is disabled returns the original object provided with no performance penalty.
- *
- * @param obj the original object to proxy.
- * @param classes the classes of the interfaces implemented by the original object and proxy object returned.
- * @return the java.lang.reflect.Proxy object associated or the original object when GProxy is disabled.
- */
- public static Object create(Object obj,Class>[] classes)
- {
- return GProxyDefaultImpl.createStatic(obj, classes);
- }
-}
diff --git a/relproxy/src/main/java/com/innowhere/relproxy/gproxy/GProxyConfig.java b/relproxy/src/main/java/com/innowhere/relproxy/gproxy/GProxyConfig.java
deleted file mode 100644
index 0184f5f..0000000
--- a/relproxy/src/main/java/com/innowhere/relproxy/gproxy/GProxyConfig.java
+++ /dev/null
@@ -1,43 +0,0 @@
-
-package com.innowhere.relproxy.gproxy;
-
-import com.innowhere.relproxy.RelProxyOnReloadListener;
-
-/**
- * Interface implemented by the configuration object needed to initialize GProxy.
- *
- *
- * @see GProxy#init(GProxyConfig)
- * @author Jose Maria Arranz Santamaria
- */
-public interface GProxyConfig
-{
- /**
- * Sets whether automatic detection of source code changes is enabled.
- *
- *
If set to false other configuration parameters are ignored, there is no automatic source code change detection/reload and original objects are returned
- * instead of proxies, performance penalty is zero. Setting to false is recommended in production whether source code change detection/reload is not required.
- *
- * @param enabled whether automatic source code change detection and reload is enabled. By default is true.
- * @return this object for flow API use.
- */
- public GProxyConfig setEnabled(boolean enabled);
-
- /**
- * Sets the class reload listener.
- *
- * @param relListener the class reload listener. By default is null.
- * @return this object for flow API use.
- */
- public GProxyConfig setRelProxyOnReloadListener(RelProxyOnReloadListener relListener);
-
- /**
- * Sets the object implementing the GroovyScriptEngine wrapper used to reload Groovy classes.
- *
- *
This parameter is required otherwise there is no bridge between RelProxy and Groovy because there is no explicit Groovy dependency in RelProxy.
- *
- * @param engine the GroovyScriptEngine wrapper.
- * @return this object for flow API use.
- */
- public GProxyConfig setGProxyGroovyScriptEngine(GProxyGroovyScriptEngine engine);
-}
diff --git a/relproxy/src/main/java/com/innowhere/relproxy/gproxy/GProxyGroovyScriptEngine.java b/relproxy/src/main/java/com/innowhere/relproxy/gproxy/GProxyGroovyScriptEngine.java
deleted file mode 100644
index 7294bcd..0000000
--- a/relproxy/src/main/java/com/innowhere/relproxy/gproxy/GProxyGroovyScriptEngine.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.innowhere.relproxy.gproxy;
-
-/**
- * Interface to implement the object implementing the GroovyScriptEngine wrapper used to reload Groovy classes.
- *
- *
The following is a very simple example of the required implementation, groovyEngine is the groovy.util.GroovyScriptEngine
- * object:
-
- def gproxyGroovyEngine = {
- String scriptName -> return (java.lang.Class)groovyEngine.loadScriptByName(scriptName)
- } as GProxyGroovyScriptEngine;
-
- *
- *
- * @see GProxyConfig#setGProxyGroovyScriptEngine(GProxyGroovyScriptEngine)
- * @author Jose Maria Arranz Santamaria
- */
-public interface GProxyGroovyScriptEngine
-{
- /**
- * The class implementing this method must call the method groovy.util.GroovyScriptEngine.loadScriptByName(String scriptName) passing
- * the scriptName.
- *
- *
This method is called by GProxy when it needs to get the Class associated to the specified Groovy script/class to check if this class
- * has changed because Groovy has reloaded the class when a source code has been detected.
- *
- * @param scriptName the name of the Groovy script/class.
- * @return the class associated to the specified Groovy script.
- */
- public Class loadScriptByName(String scriptName);
-}
diff --git a/relproxy/src/main/java/com/innowhere/relproxy/gproxy/package.html b/relproxy/src/main/java/com/innowhere/relproxy/gproxy/package.html
deleted file mode 100644
index 3cbf0dc..0000000
--- a/relproxy/src/main/java/com/innowhere/relproxy/gproxy/package.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-Contains the classes related with Groovy support of RelProxy.
-
-
-
diff --git a/relproxy/src/main/java/com/innowhere/relproxy/impl/FileExt.java b/relproxy/src/main/java/com/innowhere/relproxy/impl/FileExt.java
deleted file mode 100644
index 0533f75..0000000
--- a/relproxy/src/main/java/com/innowhere/relproxy/impl/FileExt.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.innowhere.relproxy.impl;
-
-import com.innowhere.relproxy.RelProxyException;
-import java.io.File;
-import java.io.IOException;
-
-/**
- *
- * @author jmarranz
- */
-public class FileExt
-{
- protected final File file;
- protected final String cannonicalPath; // El obtener el cannonicalPath exige acceder al sistema de archivos, por eso nos inventamos esta clase, para evitar sucesivas llamadas a File.getCanonicalPath()
-
- public FileExt(File file)
- {
- this.file = file;
- try { this.cannonicalPath = file.getCanonicalPath(); }
- catch (IOException ex) { throw new RelProxyException(ex); }
- }
-
- public File getFile()
- {
- return file;
- }
-
- public String getCanonicalPath()
- {
- return cannonicalPath;
- }
-}
diff --git a/relproxy/src/main/java/com/innowhere/relproxy/impl/GenericProxyImpl.java b/relproxy/src/main/java/com/innowhere/relproxy/impl/GenericProxyImpl.java
deleted file mode 100644
index 7a0afcf..0000000
--- a/relproxy/src/main/java/com/innowhere/relproxy/impl/GenericProxyImpl.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.innowhere.relproxy.impl;
-
-import com.innowhere.relproxy.RelProxyException;
-import com.innowhere.relproxy.RelProxyOnReloadListener;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Proxy;
-
-/**
- *
- * @author jmarranz
- */
-public abstract class GenericProxyImpl
-{
- protected RelProxyOnReloadListener reloadListener;
-
- public GenericProxyImpl()
- {
- }
-
- public static void checkSingletonNull(GenericProxyImpl singleton)
- {
- if (singleton != null)
- throw new RelProxyException("Already initialized");
- }
-
- protected static void checkSingletonExists(GenericProxyImpl singleton)
- {
- if (singleton == null)
- throw new RelProxyException("Execute first the init method");
- }
-
- protected void init(GenericProxyConfigBaseImpl config)
- {
- this.reloadListener = config.getRelProxyOnReloadListener();
- }
-
- public RelProxyOnReloadListener getRelProxyOnReloadListener()
- {
- return reloadListener;
- }
-
- public T create(T obj,Class clasz)
- {
- if (obj == null) return null;
-
- return (T)create(obj,new Class[] { clasz });
- }
-
- public Object create(Object obj,Class[] classes)
- {
- if (obj == null) return null;
-
- InvocationHandler handler = createGenericProxyInvocationHandler(obj);
-
- Object proxy = Proxy.newProxyInstance(obj.getClass().getClassLoader(),classes, handler);
- return proxy;
- }
-
-
- public abstract GenericProxyInvocationHandler createGenericProxyInvocationHandler(Object obj);
-}
diff --git a/relproxy/src/main/java/com/innowhere/relproxy/impl/GenericProxyInvocationHandler.java b/relproxy/src/main/java/com/innowhere/relproxy/impl/GenericProxyInvocationHandler.java
deleted file mode 100644
index e9fba8c..0000000
--- a/relproxy/src/main/java/com/innowhere/relproxy/impl/GenericProxyInvocationHandler.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.innowhere.relproxy.impl;
-
-import com.innowhere.relproxy.RelProxyOnReloadListener;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-/**
- *
- * @author jmarranz
- */
-public abstract class GenericProxyInvocationHandler implements InvocationHandler
-{
- protected GenericProxyImpl root;
- protected GenericProxyVersionedObject verObj;
-
- public GenericProxyInvocationHandler(GenericProxyImpl root)
- {
- this.root = root;
- }
-
- private Object getCurrent()
- {
- return verObj.getCurrent();
- }
-
- private Object getNewVersion() throws Throwable
- {
- return verObj.getNewVersion();
- }
-
- @Override
- public synchronized Object invoke(Object proxy, Method method, Object[] args) throws Throwable
- {
- Object oldObj = getCurrent();
- Object obj = getNewVersion();
-
- RelProxyOnReloadListener reloadListener = root.getRelProxyOnReloadListener();
- if (oldObj != obj && reloadListener != null)
- reloadListener.onReload(oldObj,obj,proxy,method,args);
-
- if (args != null && args.length == 1)
- {
- // Conseguimos que en proxy1.equals(proxy2) se usen los objetos asociados no los propios proxies, para ello obtenemos el objeto asociado al parámetro
- // No hace falta que equals forme parte de la interface, pero está ahí implícitamente
- // hashCode() como no tiene params es llamado sin problema de conversiones
- Object param = args[0];
- if (param instanceof Proxy && // Si es una clase generada com.sun.proxy.$ProxyN (N=1,2...) es también derivada de Proxy
- method.getName().equals("equals") &&
- method.getReturnType().equals(boolean.class))
- {
- Class>[] paramTypes = method.getParameterTypes();
- if (paramTypes.length == 1 && paramTypes[0].equals(Object.class))
- {
- InvocationHandler paramInvHandler = Proxy.getInvocationHandler(param);
- if (paramInvHandler instanceof GenericProxyInvocationHandler)
- {
- args[0] = ((GenericProxyInvocationHandler)paramInvHandler).getCurrent(); // reemplazamos el Proxy por el objeto asociado
- }
- }
- }
- }
-
- return method.invoke(obj, args);
- }
-}
diff --git a/relproxy/src/main/java/com/innowhere/relproxy/impl/GenericProxyVersionedObject.java b/relproxy/src/main/java/com/innowhere/relproxy/impl/GenericProxyVersionedObject.java
deleted file mode 100644
index 10dc262..0000000
--- a/relproxy/src/main/java/com/innowhere/relproxy/impl/GenericProxyVersionedObject.java
+++ /dev/null
@@ -1,167 +0,0 @@
-package com.innowhere.relproxy.impl;
-
-import com.innowhere.relproxy.RelProxyException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author jmarranz
- */
-public abstract class GenericProxyVersionedObject
-{
- protected Object obj;
- protected GenericProxyInvocationHandler parent;
-
- public GenericProxyVersionedObject(Object obj,GenericProxyInvocationHandler parent)
- {
- this.obj = obj;
- this.parent = parent;
- }
-
- protected static void getTreeFields(Class clasz,Object obj,ArrayList fieldList,ArrayList