├── .gitignore ├── .travis.yml ├── README.md ├── bootloader ├── README.md ├── pom.xml └── src │ ├── main │ ├── clojure │ │ ├── cl_java_introspector │ │ │ ├── client_example.clj │ │ │ ├── core.clj │ │ │ ├── examples.clj │ │ │ └── spring.clj │ │ └── net │ │ │ └── matlux │ │ │ └── server │ │ │ └── nrepl.clj │ └── java │ │ └── net │ │ └── matlux │ │ ├── MBeanRegistration.java │ │ ├── NreplMBean.java │ │ ├── NreplServer.java │ │ ├── NreplServerSpring.java │ │ └── ReplStartup.java │ └── test │ ├── clojure │ └── cl_java_introspector │ │ └── test_app.clj │ ├── java │ └── net │ │ └── matlux │ │ ├── AppTest.java │ │ ├── MBeanTest.java │ │ ├── fixtures │ │ └── Fixtures.java │ │ └── testobjects │ │ ├── Address.java │ │ ├── Department.java │ │ └── Employee.java │ └── resources │ └── spring │ └── server-test.xml ├── clj.sh ├── examples ├── SpringMVC │ ├── pom.xml │ ├── presentation.md │ └── src │ │ └── main │ │ ├── java │ │ └── net │ │ │ └── matlux │ │ │ ├── controller │ │ │ └── ReportController.java │ │ │ └── testobjects │ │ │ ├── Address.java │ │ │ ├── Department.java │ │ │ └── Employee.java │ │ └── webapp │ │ ├── WEB-INF │ │ ├── mvc-dispatcher-servlet.xml │ │ ├── pages │ │ │ ├── displayAllEmployees.jsp │ │ │ └── displayEmployeesByCity.jsp │ │ └── web.xml │ │ ├── css │ │ └── mystyle.css │ │ └── images │ │ └── bruce.jpg ├── SpringMVCrest │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ ├── com │ │ │ └── mkyong │ │ │ │ └── common │ │ │ │ ├── controller │ │ │ │ └── JSONController.java │ │ │ │ └── model │ │ │ │ └── Shop.java │ │ └── net │ │ │ └── matlux │ │ │ └── testobjects │ │ │ ├── Address.java │ │ │ ├── Department.java │ │ │ └── Employee.java │ │ └── webapp │ │ └── WEB-INF │ │ ├── mvc-dispatcher-servlet.xml │ │ └── web.xml ├── server-no-spring │ ├── pom.xml │ ├── src │ │ └── main │ │ │ └── java │ │ │ └── net │ │ │ └── matlux │ │ │ ├── testobjects │ │ │ ├── Address.java │ │ │ ├── Department.java │ │ │ └── Employee.java │ │ │ └── testserver │ │ │ └── SimpleServerExample.java │ ├── startServer.sh │ └── stopServer.sh └── server │ ├── pom.xml │ ├── src │ └── main │ │ ├── java │ │ └── net │ │ │ └── matlux │ │ │ ├── testobjects │ │ │ ├── Address.java │ │ │ ├── Department.java │ │ │ └── Employee.java │ │ │ └── testserver │ │ │ └── SpringServerExample.java │ │ └── resources │ │ └── spring │ │ └── server-test.xml │ ├── startSpringServer.sh │ └── stopServer.sh └── presentation └── skillsmatter_nreplboot_pres.odp /.gitignore: -------------------------------------------------------------------------------- 1 | .settings 2 | .DS_Store 3 | .classpath 4 | .project 5 | .idea 6 | *.iml 7 | target -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | before_script: 3 | cd bootloader 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | nRepl hook for Java 2 | =================== 3 | 4 | [![Build Status](https://travis-ci.org/matlux/jvm-breakglass.svg?branch=master)](https://travis-ci.org/matlux/jvm-breakglass) 5 | [![Clojars Project](http://clojars.org/net.matlux/jvm-breakglass/latest-version.svg)] 6 | 7 | Background on nRepl 8 | ------------------- 9 | 10 | 11 | Setting up an [nrepl](https://github.com/clojure/tools.nrepl) can be useful to introspect into the JVM for troubleshouting/investigation or testing of regular Java applications. You can connect onto a process and use a Clojure prompt interactivelly or have client application that sends and execute Java code dynamically. It works because the code injected is Clojure and that the Clojure run-time allows to evaluate code at run-time. Furthermore Clojure interops very easily with Java i.e. you can translate pretty much any Java code into Clojure and access all your Java object from the injected Clojure code. This is the perfect tool to access the inside of your JVM process live after it has been deployed. To run any fancy change of code scenario, any data structure or call any method you don't need to redeploy your java code. You can see what your process sees in real time. This is an unvaluable tool to use to develop and maintain a java application. 12 | 13 | What is this project about? 14 | --------------------------- 15 | 16 | Clojure and REPL can be introduced into a pure Java project to improve troubleshooting without having to force a team to migrate their code away from Java. 17 | 18 | nRepl is easy to start in Clojure but it needs a tiny bit of work to inject it into your java process. If you are using Spring and Java, this project has done that for you. This project is a Maven module that you can integrate in your java project and inject easily the Repl in your application. 19 | 20 | Watch these videos to get an introduction: 21 | * [EuroClojure2014](http://vimeo.com/100425265) 22 | * [Skillsmatter Sept 2013](http://skillsmatter.com/podcast/home/the-repl-an-innovative-way-to-troubleshoot-javajvm-processes) 23 | 24 | How to install the REPL in your application with Spring 25 | ------------------------------- 26 | 27 | * insert the dependency inside your maven project 28 | 29 | ```xml 30 | 31 | net.matlux 32 | jvm-breakglass 33 | 0.0.8 34 | 35 | ``` 36 | 37 | * add the following bean to your Spring config 38 | 39 | ```xml 40 | 41 | 42 | 43 | ``` 44 | 45 | 1112 is the port number. 46 | 47 | What if I don't use Spring? 48 | --------------------------- 49 | 50 | No problems, just instanciate the following class in your application rather than using the xml spring context: 51 | ```java 52 | import net.matlux.NreplServer; 53 | new NreplServer(port) //start server listening onto port number 54 | .put("department",myObject); 55 | ``` 56 | 57 | Repeat the call to put with as many object as you want to register on the repl. The NreplServer instance is a Map onto which you can add Object instances that you can retreive later on under the repl access. 58 | 59 | MBean registration (new in R_0.0.7) 60 | ------------------ 61 | 62 | It is also possible to register the NreplServer as MBean for access via a JMX console. The registred MBean is found under the name `net.matlux:name=Nrepl`. The MBean has the following properties and operations. 63 | 64 | |Type|Name|Meaning| 65 | |----|----|-------| 66 | |Attribute|Port|Indicates the port used for the nrepl server (read/write).| 67 | |Attribute|Started|Indicates wether the NreplServer is started or not (read only).| 68 | |Operation|Start|Starts the NreplServer.| 69 | |Operation|Stop|Stops the NreplServer.| 70 | 71 | The registration/unregistration of the NReplServer to the MBeanServer must be done manually via the methods `NReplServer#registerMBean` and `NReplServer#unregisterMBean`. If you are using the NReplServer with Spring, these operations are typically preformed post construction and pre destruction. 72 | 73 | 74 | Quick demonstration of this project 75 | ----------------------------------- 76 | 77 | ## Pre-requisites: 78 | 79 | * You must have [leinengen](https://github.com/technomancy/leiningen) installed. Otherwise follow the installation process on this [site](https://github.com/technomancy/leiningen). 80 | * You must have [Maven](http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html) installed. Follow [this](http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html) otherwise. 81 | 82 | ## Tutorial 83 | 84 | * clone this repo and compile the example 85 | 86 | ```sh 87 | git clone https://github.com/matlux/jvm-breakglass.git 88 | cd jvm-breakglass/examples/server 89 | ``` 90 | 91 | * Compile this project 92 | 93 | ```sh 94 | mvn clean install 95 | ``` 96 | 97 | * Start the example of a server with the NreplServer 98 | 99 | ```sh 100 | ./startSpringServer.sh 101 | ``` 102 | 103 | You should now see the following message repeating itself on the screen: 104 | 105 | Retrieve Employees from NY or London: 106 | Retrieve Employees from NY or London: 107 | ... 108 | 109 | Notes: Ctrl-c does not seem to kill the process for some reason. Please find it's PID and kill it with `kill -9 [pid of the process]` from a different window when you've finished the demonstration. 110 | 111 | * Leave the above server running and open a different shell window before you continue 112 | 113 | Notes: You don't need to be inside the current directory of any particular project. Actually it's best to be outside of any project so you don't pull any specific project dependencies and introduce an uncertainty. If in doubt, type `cd /tmp` to make sure you're outside of any specific Lein project. 114 | 115 | * Start the repl client which introspects into the Java server process 116 | 117 | ```sh 118 | lein repl :connect localhost:1112 119 | ``` 120 | 121 | * Copy and past the following commands 122 | 123 | ```clojure 124 | (use 'cl-java-introspector.spring) 125 | (use 'cl-java-introspector.core) 126 | (use 'me.raynes.fs) 127 | 128 | ``` 129 | 130 | * Type one of the following Commands 131 | 132 | ```clojure 133 | ;list beans 134 | (get-beans) 135 | 136 | ;find a bean or an object 137 | (get-bean "department") 138 | 139 | ;what methods or fields has the obj? 140 | (methods-info (get-bean "department")) 141 | 142 | ``` 143 | 144 | * what next? 145 | 146 | See more [examples](https://github.com/matlux/jvm-breakglass/blob/master/bootloader/src/main/clojure/cl_java_introspector/examples.clj). 147 | 148 | Quick demonstration of a standard Java Server example 149 | ----------------------------------------------------- 150 | 151 | * clone this repo and compile the example 152 | 153 | ```sh 154 | git clone https://github.com/matlux/jvm-breakglass.git 155 | cd jvm-breakglass/examples/server-no-spring 156 | ``` 157 | 158 | * Compile this project 159 | 160 | ```sh 161 | mvn clean install 162 | ``` 163 | 164 | * Start the example of a server with the NreplServer 165 | 166 | ```sh 167 | ./startServer.sh 168 | ``` 169 | 170 | * Start the repl client which introspects into the Java server process 171 | 172 | ```sh 173 | lein repl :connect localhost:1112 174 | ``` 175 | 176 | * Copy and past the following commands 177 | 178 | ```clojure 179 | (use 'cl-java-introspector.core) 180 | (use 'me.raynes.fs) 181 | 182 | ``` 183 | 184 | * Type one of the following Commands 185 | 186 | ```clojure 187 | ;list objs 188 | (get-objs) 189 | 190 | ;find a bean or an object 191 | (get-obj "department") 192 | 193 | ;what methods or fields has the obj? 194 | (methods-info (get-obj "departement")) 195 | 196 | ``` 197 | 198 | * what next? 199 | 200 | See section below with more use cases. 201 | or 202 | See more [examples](https://github.com/matlux/jvm-breakglass/blob/master/bootloader/src/main/clojure/cl_java_introspector/examples.clj). 203 | 204 | 205 | # There are two type of client to access the nRepl server 206 | 207 | ## Via the repl client with lein 208 | 209 | ```sh 210 | lein repl :connect [host:port] 211 | ``` 212 | 213 | for example: 214 | 215 | ```sh 216 | lein repl :connect localhost:1112 217 | ``` 218 | 219 | ## programatically 220 | 221 | ```clojure 222 | (require '[clojure.tools.nrepl :as repl]) 223 | (with-open [conn (repl/connect :port 1112)] 224 | (-> (repl/client conn 1000) 225 | (repl/message {:op :eval :code "(+ 1 1)"}) 226 | repl/response-values)) 227 | ``` 228 | 229 | The above sends an expression "(+ 1 1)" to be evaluated remotely. See [nrepl](https://github.com/clojure/tools.nrepl) website for more details. 230 | 231 | Also see quick demo above. 232 | 233 | # Once you have the nRepl running inside your process. What can you do? 234 | 235 | You need to connect onto it with the lein command above and the set of imports (also above). Now you can type any of the following commands. 236 | 237 | 238 | ## retrieve the list of System properties from the java process 239 | 240 | ```clojure 241 | (filter #(re-matches #"sun.*" (key %)) (into {} (System/getProperties))) 242 | ``` 243 | 244 | This example filters on a regex. It retrieves property keys which start with "sun" 245 | 246 | ## list bean or objects 247 | 248 | ```Clojure 249 | (get-beans) ; spring example 250 | (get-objs) ; standard java example 251 | ``` 252 | 253 | ## retrieve a bean or an object by name 254 | 255 | ```clojure 256 | (get-bean "department") ; spring example 257 | (get-obj "department") ; standard java example 258 | ``` 259 | 260 | keep the object reference 261 | ```clojure 262 | (def myobj (get-bean "department")) ; spring example 263 | ;;or 264 | (def myobj (get-obj "department")) ; standard java example 265 | ``` 266 | 267 | ## what methods or fields has the obj? 268 | 269 | ```clojure 270 | (methods-info myobj) 271 | (fields-info myobj) 272 | ``` 273 | 274 | ## show the content of the fields the obj 275 | 276 | ```clojure 277 | (to-tree myobj) 278 | ``` 279 | 280 | ## Terminate the process ;) 281 | 282 | ```clojure 283 | (System/exit 0) 284 | ``` 285 | 286 | ### Retrieve the Spring application context 287 | 288 | ```clojure 289 | (import '(net.matlux NreplServerSpring)) 290 | 291 | 292 | (. NreplServerSpring/instance getApplicationContext) 293 | 294 | ;; for example list all the bean names 295 | (. (. NreplServerSpring/instance getApplicationContext) getBeanDefinitionNames) 296 | ``` 297 | 298 | 299 | ## Coherence example: Retrieve the number of object in a Cache 300 | 301 | Your application needs to have a dependency on Oracle Coherence, The binary and dependency is not provided here, this is just an example. 302 | 303 | ```clojure 304 | (def all-filter (new AlwaysFilter)) 305 | (def nodeCache (Caches/getCache "cachename") 306 | (let [all-filter (new AlwaysFilter) 307 | nodeCache (Caches/getCache "cachename")] 308 | (. (. nodeCache entrySet all-filter) size)) 309 | ``` 310 | 311 | 312 | ## Introspect into a Java bean (not a Spring one this time...) 313 | 314 | ```clojure 315 | (bean obj) 316 | ``` 317 | 318 | ## Introspect into a Java Object 319 | 320 | ```clojure 321 | (to-tree myObject) 322 | ``` 323 | 324 | For example: 325 | 326 | ```java 327 | Department department = new Department("The Art Department",0L); 328 | department.add(new Employee("Bob","Dilan",new Address("1 Mayfair","SW1","London"))); 329 | department.add(new Employee("Mick","Jagger",new Address("1 Time Square",null,"NY"))); 330 | objMap.put("department", department); 331 | Set myFriends = new HashSet(); 332 | myFriends.add(new Employee("Keith","Richard",new Address("2 Mayfair","SW1","London"))); 333 | myFriends.add(new Employee("Nina","Simone",new Address("1 Gerards Street","12300","Smallville"))); 334 | objMap.put("myFriends", myFriends); 335 | objMap.put("nullValue", null); 336 | ``` 337 | 338 | becomes 339 | 340 | ```clojure 341 | [{objMap {myFriends [{address {city Smallville, zipcode 12300, street 1 Gerards Street}, lastname Simone, firstname Nina} {address {city London, zipcode SW1, street 2 Mayfair}, lastname Richard, firstname Keith}], nullValue nil, department {id 0, name The Art Department, employees [{address {city London, zipcode SW1, street 1 Mayfair}, lastname Dilan, firstname Bob} {address {city NY, zipcode nil, street 1 Time Square}, lastname Jagger, firstname Mick}]}}} nil] 342 | ``` 343 | 344 | See [cl-java-introspector.core](https://github.com/matlux/jvm-breakglass/blob/master/bootloader/src/main/clojure/cl_java_introspector/core.clj) for details of the implementation. 345 | 346 | 347 | 348 | ## License 349 | 350 | Copyright (C) 2015 Mathieu Gauthron 351 | 352 | Distributed under the Eclipse Public License, the same as Clojure. 353 | -------------------------------------------------------------------------------- /bootloader/README.md: -------------------------------------------------------------------------------- 1 | # How to release with signature with maven: 2 | 3 | * change 0.0.8 (pom.xml) 4 | * change to current git revision (pom.xml) 5 | * git commit -m "release R_0.0.8" -a 6 | * add tag R_0.0.8 7 | ``` 8 | mvn verify gpg:sign install:install deploy:deploy 9 | ``` 10 | * git tag -a R_0.0.8 -m "Release of version 0.0.8" 2881362 11 | * change to SNAPSHOT in pom.xml 12 | * git commit -m "changed version to 0.0.8-SNAPSHOT" -a 13 | * git push 14 | * git push --tags 15 | 16 | Make sure you add clojars to the pom.xml: 17 | 18 | bc. 19 | 20 | clojars 21 | Clojars repository 22 | https://clojars.org/repo 23 | 24 | 25 | 26 | Add authentication info to settings.xml: 27 | 28 | bc. 29 | clojars 30 | username 31 | password 32 | 33 | 34 | 35 | # How to release without signature: 36 | 37 | scp -i ~/.ssh/id_rsa... pom.xml target/jvm-breakglass-0.0.5.jar clojars@clojars.org: 38 | 39 | 40 | -------------------------------------------------------------------------------- /bootloader/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | net.matlux 5 | jvm-breakglass 6 | jar 7 | 0.0.9-SNAPSHOT 8 | http://www.matlux.net 9 | Setting up an nrepl can be useful to introspect into the JVM for troubleshouting/investigation or testing of regular Java applications. You can connect onto a process and use a Clojure prompt interactivelly or have client application that sends and execute Java code dynamically. It works because the code injected is Clojure and that the Clojure run-time allows to evaluate code at run-time. Furthermore Clojure interops very easily with Java i.e. you can translate pretty much any Java code into Clojure and access all your Java object from the injected Clojure code. This is the perfect tool to access the inside of your JVM process live after it has been deployed. To run any fancy change of code scenario, any data structure or call any method you don't need to redeploy your java code. You can see what your process sees in real time. This is an unvaluable tool to use to develop and maintain a java application. 10 | 11 | Matlux Ltd. 12 | http://www.matlux.net 13 | 14 | 15 | 16 | Copyright (C) 2014 Mathieu Gauthron. Distributed under the Eclipse Public License. 17 | http://opensource.org/licenses/eclipse-1.0.php 18 | repo 19 | Same as Clojure. 20 | 21 | 22 | 23 | https://github.com/matlux/jvm-breakglass.git 24 | git@github.com:matlux/jvm-breakglass.git 25 | d2b037c 26 | https://github.com/matlux/jvm-breakglass 27 | 28 | 29 | 30 | 31 | com.theoryinpractise 32 | clojure-maven-plugin 33 | 1.3.10 34 | 35 | 36 | compile 37 | compile 38 | 39 | compile 40 | 41 | 42 | 43 | test 44 | test 45 | 46 | test 47 | 48 | 49 | 50 | 51 | 52 | org.apache.maven.plugins 53 | maven-compiler-plugin 54 | 3.1 55 | 56 | 1.6 57 | 1.6 58 | 59 | 60 | 61 | 62 | 63 | src/main/clojure 64 | 65 | 66 | src/test/resources 67 | 68 | 69 | 70 | 71 | src/test/clojure 72 | 73 | 74 | src/test/java 75 | 76 | 77 | 78 | 79 | 80 | org.clojure 81 | clojure 82 | 1.6.0 83 | 84 | 85 | org.clojure 86 | tools.nrepl 87 | 0.2.6 88 | 89 | 90 | me.raynes 91 | fs 92 | 1.4.6 93 | 94 | 95 | org.springframework 96 | spring-web 97 | 3.0.7.RELEASE 98 | provided 99 | 100 | 101 | junit 102 | junit 103 | 4.12 104 | test 105 | 106 | 107 | 108 | 109 | clojars.org 110 | http://clojars.org/repo 111 | 112 | 113 | 114 | 115 | clojars 116 | Clojars repository 117 | https://clojars.org/repo 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /bootloader/src/main/clojure/cl_java_introspector/client_example.clj: -------------------------------------------------------------------------------- 1 | (ns cl-java-introspector.client-example) 2 | 3 | (require '[clojure.tools.nrepl :as repl]) 4 | 5 | 6 | (defn remote-execute [hostname port code] 7 | (try 8 | (with-open [conn (repl/connect :host hostname :port port)] 9 | (-> (repl/client conn 1000) 10 | (repl/message {:op :eval :code code}) 11 | repl/response-values)) 12 | (catch java.net.ConnectException e 13 | ;(println "Caught" (.getMessage e)) 14 | "cannot connect") 15 | (finally 16 | ;(println "") 17 | ))) 18 | 19 | 20 | 21 | (def code2inject 22 | "(import '(net.matlux NreplServerStartup)) 23 | (import '(java.lang.reflect Modifier)) 24 | (import '(net.matlux NreplServerWithSpringLog4jStartup)) 25 | (defn obj2map [obj] 26 | (let [obj2fields (fn [obj] (map #(do (.setAccessible % true) %) (into [] (. (. obj getClass) getDeclaredFields)))) 27 | get-inst-fields (fn [fields] (filter #(not (Modifier/isStatic (.getModifiers %))) fields)) 28 | field2ref (fn [field obj] (.get field obj)) 29 | ] 30 | ;(reduce #(assoc %1 (.getName %2) (field2value %2)) {} in-fields) 31 | (cond (nil? obj) nil 32 | (instance? java.lang.String obj) obj 33 | (instance? java.lang.Number obj) obj 34 | (instance? java.lang.Iterable obj) (into [] (map (fn [e] (obj2map e)) (into [] obj))) 35 | (instance? java.util.Map obj) (let [m (into {} obj) 36 | ks (keys m) 37 | ] 38 | (reduce #(assoc %1 %2 (obj2map (m %2))) {} ks)) 39 | :else (reduce #(assoc %1 (.getName %2) (obj2map (field2ref %2 obj))) {} (get-inst-fields (obj2fields obj))) ) 40 | ))") 41 | 42 | (def code2execute 43 | "(obj2map NreplServerStartup/instance) 44 | (into [] (.getBeanDefinitionNames (.getApplicationContext NreplServerWithSpringLog4jStartup/instance))) 45 | (obj2map (.getObj NreplServerWithSpringLog4jStartup/instance \"department\")) 46 | (obj2map (.getObj NreplServerWithSpringLog4jStartup/instance \"employee1\")) 47 | (obj2map nil)") 48 | 49 | 50 | (defn -main [] 51 | 52 | (println "introspecting objects:") 53 | (remote-execute "localhost" 1112 code2inject) 54 | (println (remote-execute "localhost" 1112 code2execute)) 55 | (System/exit 0) 56 | ) 57 | 58 | -------------------------------------------------------------------------------- /bootloader/src/main/clojure/cl_java_introspector/core.clj: -------------------------------------------------------------------------------- 1 | (ns cl-java-introspector.core) 2 | 3 | (require '[clojure.walk :only [walk prewalk postwalk]]) 4 | (use 'clojure.reflect 'clojure.pprint) 5 | 6 | (import '(net.matlux NreplServer)) 7 | (import '(java.lang.reflect Modifier)) 8 | 9 | 10 | 11 | 12 | (defn get-objs [] 13 | (into [] (.keySet NreplServer/instance)) 14 | ) 15 | 16 | 17 | 18 | (defn get-obj [^String bean-name] 19 | (.getObj NreplServer/instance bean-name)) 20 | 21 | 22 | (defn methods-info [obj] 23 | (print-table (sort-by :name (filter :exception-types (:members (reflect obj)))))) 24 | (defn fields-info [obj] 25 | (print-table (sort-by :name (filter :type (:members (reflect obj)))))) 26 | (defn members-info [obj] 27 | (print-table (sort-by :name (:members (reflect obj))))) 28 | 29 | (defn field? [field] (not (Modifier/isStatic (.getModifiers field)))) 30 | (defn get-fields [obj] (map #(vector (keyword (.getName %)) (.get % obj)) (filter field? (map #(do (.setAccessible % true) %) (into [] (. (. obj getClass) getDeclaredFields)))))) 31 | (def primitive? (some-fn string? number?)) 32 | (def clojure-struct? (some-fn map? set? vector? list?)) 33 | 34 | (defn- objfields-to-map [obj] (reduce #(let [[fname ob] %2] (assoc %1 fname ob )) {} (get-fields obj))) 35 | 36 | (defn- to-map [obj2map obj] 37 | ;(print "walk:") (prn obj) 38 | (cond 39 | ((some-fn nil? primitive? clojure-struct? keyword?) obj) obj 40 | (instance? java.lang.Iterable obj) (into [] obj) 41 | (instance? java.util.Map obj) (let [m (into {} obj)] (reduce #(assoc %1 (if (string? %2) (keyword %2) %2) (m %2)) {} (keys m))) 42 | :else (obj2map obj) 43 | )) 44 | 45 | (def to-tree (partial clojure.walk/prewalk (partial to-map objfields-to-map))) 46 | 47 | (defn get-obj-methods [obj] 48 | (let [obj2methods (fn [obj] (map #(do (.setAccessible % true) %) (into [] (. (. obj getClass) getDeclaredMethods)))) 49 | get-inst-methods (fn [fields] (filter #(not (Modifier/isStatic (.getModifiers %))) fields)) 50 | method2ref (fn [field obj] (.get field obj)) 51 | ] 52 | 53 | (obj2methods obj))) 54 | 55 | (defn get-method-names [obj] (map #(.getName %) (get-obj-methods obj))) 56 | 57 | (defn obj2map [obj level] 58 | (if (zero? level) obj (let [obj2fields (fn [obj] (map #(do (.setAccessible % true) %) (into [] (. (. obj getClass) getDeclaredFields)))) 59 | get-inst-fields (fn [fields] (filter #(not (Modifier/isStatic (.getModifiers %))) fields)) 60 | field2ref (fn [field obj] (.get field obj)) 61 | ] 62 | ;(reduce #(assoc %1 (.getName %2) (field2value %2)) {} in-fields) 63 | (cond (nil? obj) nil 64 | (instance? java.lang.String obj) obj 65 | (instance? java.lang.Number obj) obj 66 | (instance? java.lang.Iterable obj) (into [] (map (fn [e] (obj2map e (dec level))) (into [] obj))) 67 | (instance? java.util.Map obj) (let [m (into {} obj) 68 | ks (keys m) 69 | ] 70 | (reduce #(assoc %1 %2 (obj2map (m %2) (dec level))) {} ks)) 71 | :else (reduce #(assoc %1 (.getName %2) (obj2map (field2ref %2 obj) (dec level))) {} (get-inst-fields (obj2fields obj))) ) 72 | ))) 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /bootloader/src/main/clojure/cl_java_introspector/examples.clj: -------------------------------------------------------------------------------- 1 | (ns cl-java-introspector.examples) 2 | 3 | (comment 4 | ;;preparation 5 | (do 6 | (import '(net.matlux NreplServerSpring)) 7 | (import '(net.matlux NreplServer)) 8 | 9 | (use 'cl-java-introspector.spring) 10 | (use 'cl-java-introspector.core) 11 | (import 'net.matlux.testobjects.Address) 12 | (use 'clojure.reflect 'clojure.pprint 'clojure.java.javadoc) 13 | (use 'me.raynes.fs)) 14 | 15 | ;;intro 16 | (System/getProperties) 17 | (list-dir ".") 18 | *cwd* 19 | ;;demonstrate how we can search through ns to find a function of a lib like "fs" 20 | (->> (ns-map *ns*) (filter #(re-find #"fs" (.toString (val %)))) (map key)) 21 | 22 | 23 | ;;demonstrate a shell like pipping with aiming for this: 24 | (find-files ".." #".*") 25 | (->> (find-files ".." #".*") (map absolute-path) (filter #(and (re-find #"conf" %) (directory? %)))) 26 | 27 | ;do following twice: 28 | ;list beans 29 | (get-objs) ; standard java example 30 | (get-beans) ; spring example 31 | ;retrieve a bean or an object 32 | (get-bean "reportController") ; spring example 33 | (get-bean "department") ; spring example ( 8 mins) 34 | (get-obj "department") ; standard java example 35 | 36 | ; can we see inside private members? 37 | (bean (get-bean "department")) 38 | (to-tree (get-bean "department")) 39 | (obj2map (get-bean "department") 5) 40 | 41 | 42 | ;;what methods or fields has the obj? 43 | (methods-info (get-bean "department")) 44 | (fields-info (get-bean "department")) 45 | 46 | 47 | ; what is the bug? 48 | (->> (get-obj "department") .getEmployees) 49 | ; get hold of the two employees 50 | (->> (get-obj "department") .getEmployees (map #(vector (keyword (.getFirstname %)) %)) (into {})) 51 | (->> (get-obj "department") .getEmployees (group-by #(keyword (.getFirstname %)))) 52 | (def employees (->> (get-obj "department") .getEmployees (into []) (map #(vector (keyword (.getFirstname %)) %)) (into {}))) 53 | 54 | (:Mick employees) 55 | (methods-info (:Mick employees)) 56 | (->> (:Mick employees) .getAddress) 57 | (->> (:Mick employees) .getAddress methods-info) 58 | ;; here it is: 59 | (->> (:Mick employees) .getAddress .getCity) 60 | (->> (:Mick employees) .getAddress .getStreet) 61 | 62 | 63 | ;creation of new obj instance and overwrite class definition on the fly 64 | (proxy [Address] ["1 Mayfair","SW1","London"]) 65 | (.getCity (proxy [Address] ["1 Mayfair","SW1","London"])) 66 | (def new-addr (proxy [Address] ["1 Mayfair","SW1","London"] (getStreet [] "53 Victoria Str") (getCity [] "London"))) 67 | (def new-addr (proxy [Address] ["1 Madison Square","SW2","NY"] (getStreet [] "1 Madison Square") (getCity [] "NY"))) 68 | (.getCity new-addr) 69 | 70 | ;; fixing bug 71 | (.setAddress (:Mick employees) new-addr) 72 | 73 | 74 | 75 | 76 | 77 | (.setAddress (:Bob employees) (proxy [Address] ["1 Mayfair","SW1","London"] (getStreet [] "53 Victoria Str") (getCity [] "London"))) 78 | 79 | ;; verify fix 80 | (->> (:Mick employees) .getAddress .getCity) 81 | 82 | (net.matlux.testobjects.Employee. "John" "Smith" (proxy [net.matlux.testobjects.Address] ["53 Victoria Str" "SE1 0LK" "London"] (boo [other] false))) 83 | 84 | 85 | ;how about using clojure as a remote shell and listing some files? 86 | (list-dir ".") 87 | *cwd* 88 | (hidden? ".") 89 | (hidden? "pom.xml") 90 | (hidden? ".classpath") 91 | (directory? ".classpath") 92 | (directory? ".") 93 | (filter #(directory? (str "../" %)) (list-dir "..")) 94 | 95 | ;;demonstrate how we can search through ns to find a function of a lib like "fs" 96 | (->> (ns-map *ns*) (filter #(re-find #"fs" (.toString (val %)))) (map key)) 97 | (->> (ns-map *ns*) (filter #(re-find #"javadoc" (.toString (val %)))) (map key)) 98 | 99 | 100 | (println (remote-execute "localhost" 1112 code2execute2)) 101 | 102 | 103 | ;(get-obj-methods "") 104 | ;(->> NreplServerStartup/instance get-member-fields first second get-member-fields) 105 | ;(->> NreplServerStartup/instance get-member-fields first second to-tree ) 106 | ;(->> NreplServerStartup/instance get-member-fields first second to-tree :department get-obj-methods first bean) 107 | ;(->> (to-tree NreplServerStartup/instance) :objMap :department :employees second :lastname) 108 | 109 | (->> (get-obj "department") .getEmployees (map #(.getAddress %)) ) 110 | (->> (get-obj "department") .getEmployees (map #(.getAddress %)) first) 111 | (->> (get-obj "department") .getEmployees (map #(.getAddress %)) first methods-info) 112 | (->> (get-obj "department") .getEmployees (map #(->> (.getAddress %) .getCity)) ) 113 | 114 | 115 | ) 116 | -------------------------------------------------------------------------------- /bootloader/src/main/clojure/cl_java_introspector/spring.clj: -------------------------------------------------------------------------------- 1 | (ns cl-java-introspector.spring) 2 | 3 | (require '[clojure.walk :only [walk prewalk postwalk]]) 4 | (use 'clojure.reflect 'clojure.pprint) 5 | (use '[cl-java-introspector.core :exclude [get-obj]]) 6 | 7 | (import '(net.matlux NreplServer)) 8 | (import '(net.matlux NreplServerSpring)) 9 | (import '(java.lang.reflect Modifier)) 10 | 11 | 12 | 13 | 14 | 15 | (defn get-beans [] 16 | (into [] (.getBeanDefinitionNames (.getApplicationContext NreplServerSpring/instance))) 17 | ) 18 | 19 | 20 | 21 | (defn get-bean [^String bean-name] 22 | (.getObj NreplServerSpring/instance bean-name)) 23 | 24 | ;(def get-obj get-bean) 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /bootloader/src/main/clojure/net/matlux/server/nrepl.clj: -------------------------------------------------------------------------------- 1 | (ns net.matlux.server.nrepl) 2 | 3 | (use '[clojure.tools.nrepl.server :only (start-server stop-server)]) 4 | 5 | (def server nil) 6 | 7 | (defn safe-stop-server [server] 8 | (when (not (nil? server)) 9 | (stop-server server))) 10 | 11 | (defn start-server-now [port] 12 | (alter-var-root (var server) (fn [old-server] 13 | (safe-stop-server old-server) 14 | (start-server :port port)))) 15 | 16 | (defn stop-server-now [] 17 | (alter-var-root (var server) (fn [old-server] 18 | (safe-stop-server old-server) 19 | nil))) -------------------------------------------------------------------------------- /bootloader/src/main/java/net/matlux/MBeanRegistration.java: -------------------------------------------------------------------------------- 1 | package net.matlux; 2 | 3 | import javax.management.InstanceAlreadyExistsException; 4 | import javax.management.MBeanRegistrationException; 5 | import javax.management.MBeanServer; 6 | import javax.management.MalformedObjectNameException; 7 | import javax.management.NotCompliantMBeanException; 8 | import javax.management.ObjectName; 9 | import javax.management.StandardMBean; 10 | import java.lang.management.ManagementFactory; 11 | import java.util.logging.Level; 12 | import java.util.logging.Logger; 13 | 14 | public final class MBeanRegistration { 15 | 16 | private static final Logger LOGGER = Logger.getLogger(MBeanRegistration.class.getSimpleName()); 17 | 18 | public static void registerNreplServerAsMBean(NreplMBean nreplServer, boolean logExceptionStack) { 19 | try { 20 | MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 21 | registerMBean(mbs, getObjectName(), nreplServer); 22 | LOGGER.log(Level.INFO, "MBean Registration of JVM-breakglass successful"); 23 | } catch (Exception e) { 24 | if (logExceptionStack) LOGGER.log(Level.SEVERE, "MBean Registration of JVM-breakglass not successful", e); 25 | else LOGGER.log(Level.INFO, "MBean Registration of JVM-breakglass not successful"); 26 | throw new RuntimeException("MBean Registration of JVM-breakglass not successful", e); 27 | } 28 | } 29 | 30 | public static void unregisterNreplServerAsMBean(boolean logExceptionStack) { 31 | try { 32 | MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 33 | mbs.unregisterMBean(getObjectName()); 34 | LOGGER.log(Level.INFO, "MBean Unregistration of JVM-breakglass successful"); 35 | } catch (Exception e) { 36 | if (logExceptionStack) LOGGER.log(Level.SEVERE, "MBean Unregistration of JVM-breakglass not successful", e); 37 | else LOGGER.log(Level.INFO, "MBean Unregistration of JVM-breakglass not successful"); 38 | throw new RuntimeException("MBean Unregistration of JVM-breakglass not successful", e); 39 | } 40 | } 41 | 42 | public static ObjectName getObjectName() throws MalformedObjectNameException { 43 | return new ObjectName("net.matlux:name=Nrepl"); 44 | } 45 | 46 | private static void registerMBean(MBeanServer mbs, ObjectName objectName, NreplMBean nreplServer) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException { 47 | StandardMBean mbean = new StandardMBean(nreplServer, NreplMBean.class, false); 48 | mbs.registerMBean(mbean, objectName); 49 | } 50 | 51 | private MBeanRegistration() { 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /bootloader/src/main/java/net/matlux/NreplMBean.java: -------------------------------------------------------------------------------- 1 | package net.matlux; 2 | 3 | public interface NreplMBean { 4 | 5 | int getPort(); 6 | 7 | void setPort(int port); 8 | 9 | boolean isStarted(); 10 | 11 | boolean start(); 12 | 13 | boolean stop(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /bootloader/src/main/java/net/matlux/NreplServer.java: -------------------------------------------------------------------------------- 1 | package net.matlux; 2 | 3 | 4 | 5 | import java.util.Collection; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | import java.util.Set; 9 | import java.util.logging.Level; 10 | import java.util.logging.Logger; 11 | 12 | import clojure.lang.Symbol; 13 | import clojure.lang.Var; 14 | import clojure.lang.RT; 15 | 16 | /** 17 | * NreplServer 18 | * 19 | */ 20 | public class NreplServer implements Map, NreplMBean 21 | { 22 | private static final Logger LOGGER = Logger.getLogger(NreplServer.class.getSimpleName()); 23 | 24 | static public NreplServer instance=null; 25 | 26 | final static public int DEFAULT_PORT=1112; 27 | final static private Var USE = RT.var("clojure.core", "use"); 28 | final static private Symbol REPL_SERVER_NS = Symbol.intern("net.matlux.server.nrepl"); 29 | final static private Var START_REPL_SERVER = RT.var("net.matlux.server.nrepl", "start-server-now"); 30 | final static private Var STOP_REPL_SERVER = RT.var("net.matlux.server.nrepl","stop-server-now"); 31 | final static private Var SERVER = RT.var("net.matlux.server.nrepl", "server"); 32 | 33 | private final Map objMap = new HashMap(); 34 | private final boolean logExceptionStack; 35 | private final boolean propagateException; 36 | private int port; 37 | 38 | 39 | public NreplServer(int port, boolean startOnCreation, boolean registerMBeanOnCreation, boolean propagateException, boolean logExceptionStack) { 40 | this.port = port; 41 | this.propagateException = propagateException; 42 | this.logExceptionStack = logExceptionStack; 43 | LOGGER.info("Creating ReplStartup for Port=" + port); 44 | try { 45 | USE.invoke(REPL_SERVER_NS); 46 | } catch (Throwable t) { 47 | LOGGER.log(Level.SEVERE, "Repl initialization caught an error", t); 48 | } 49 | 50 | if (startOnCreation) { 51 | start(); 52 | } 53 | 54 | if (registerMBeanOnCreation) { 55 | registerMBean(); 56 | } 57 | 58 | instance=this; 59 | } 60 | 61 | public NreplServer(int port) { 62 | this(port, true,true,false,true); 63 | } 64 | 65 | public static void main(String[] args) throws Exception { 66 | int port=DEFAULT_PORT; 67 | if(args.length > 0) { 68 | port = Integer.parseInt(args[0]); 69 | } 70 | 71 | new NreplServer(port); 72 | } 73 | 74 | @Override 75 | public boolean start() { 76 | try { 77 | START_REPL_SERVER.invoke(port); 78 | LOGGER.info("Repl started successfully on Port = " + port); 79 | } catch (Throwable t) { 80 | if (logExceptionStack) LOGGER.log(Level.SEVERE, "Repl startup caught an error", t); 81 | else LOGGER.log(Level.INFO, "Repl startup caught an error"); 82 | if (propagateException) throw new RuntimeException("Repl startup caught an error", t); 83 | return false; 84 | } 85 | return true; 86 | } 87 | 88 | @Override 89 | public boolean stop() { 90 | try { 91 | STOP_REPL_SERVER.invoke(); 92 | LOGGER.info("Repl stopped successfully"); 93 | } catch (Throwable t) { 94 | if (logExceptionStack) LOGGER.log(Level.SEVERE, "Repl stop caught an error", t); 95 | else LOGGER.log(Level.INFO, "Repl stop caught an error"); 96 | if (propagateException) throw new RuntimeException("Repl stop caught an error", t); 97 | return false; 98 | } 99 | return true; 100 | } 101 | 102 | @Override 103 | public int getPort() { 104 | return port; 105 | } 106 | 107 | @Override 108 | public void setPort(int port) { 109 | this.port = port; 110 | } 111 | 112 | @Override 113 | public boolean isStarted() { 114 | return SERVER.deref() != null; 115 | } 116 | 117 | public void registerMBean() { 118 | MBeanRegistration.registerNreplServerAsMBean(this, logExceptionStack); 119 | } 120 | 121 | public void unregisterMBean() { 122 | MBeanRegistration.unregisterNreplServerAsMBean(logExceptionStack); 123 | } 124 | 125 | public Object getObj(String key) { 126 | return objMap.get(key); 127 | } 128 | public void setObjMap(Map objMap) { 129 | this.objMap.putAll(objMap); 130 | } 131 | 132 | @Override 133 | public int size() { 134 | return objMap.size(); 135 | } 136 | 137 | @Override 138 | public boolean isEmpty() { 139 | return objMap.isEmpty(); 140 | } 141 | 142 | @Override 143 | public boolean containsKey(Object key) { 144 | return objMap.containsKey(key); 145 | } 146 | 147 | @Override 148 | public boolean containsValue(Object value) { 149 | return objMap.containsValue(value); 150 | } 151 | 152 | @Override 153 | public Object get(Object key) { 154 | return objMap.get(key); 155 | } 156 | 157 | @Override 158 | public Object put(String key, Object value) { 159 | return objMap.put(key, value); 160 | } 161 | 162 | @Override 163 | public Object remove(Object key) { 164 | return objMap.remove(key); 165 | } 166 | 167 | @Override 168 | public void putAll(Map m) { 169 | objMap.putAll(m); 170 | 171 | } 172 | 173 | @Override 174 | public void clear() { 175 | objMap.clear(); 176 | } 177 | 178 | @Override 179 | public Set keySet() { 180 | return objMap.keySet(); 181 | } 182 | 183 | @Override 184 | public Collection values() { 185 | return objMap.values(); 186 | } 187 | 188 | @Override 189 | public Set entrySet() { 190 | return objMap.entrySet(); 191 | } 192 | 193 | } 194 | -------------------------------------------------------------------------------- /bootloader/src/main/java/net/matlux/NreplServerSpring.java: -------------------------------------------------------------------------------- 1 | package net.matlux; 2 | 3 | 4 | import org.springframework.beans.BeansException; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.context.ApplicationContext; 7 | import org.springframework.context.ApplicationContextAware; 8 | import org.springframework.context.support.ClassPathXmlApplicationContext; 9 | /** 10 | * Hello world! 11 | * 12 | */ 13 | public class NreplServerSpring extends NreplServer implements ApplicationContextAware 14 | { 15 | 16 | 17 | //static public NreplServerSpring instance=null; 18 | 19 | final static public int DEFAULT_PORT=1111; 20 | @Autowired 21 | private ApplicationContext ctx; 22 | 23 | public NreplServerSpring(int port, boolean startOnCreation, boolean registerMBeanOnCreation, boolean propagateException, boolean logExceptionStack) { 24 | super(port, startOnCreation, registerMBeanOnCreation, propagateException, logExceptionStack); 25 | } 26 | 27 | public NreplServerSpring(int port) { 28 | super(port); 29 | } 30 | 31 | public static void main(String[] args) throws Exception { 32 | ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring/server-test.xml"); 33 | } 34 | 35 | public Object getObj(String beanName) { 36 | return get(beanName); 37 | } 38 | 39 | @Override 40 | public void setApplicationContext(ApplicationContext ctx) 41 | throws BeansException { 42 | this.ctx = ctx; 43 | 44 | } 45 | 46 | public ApplicationContext getApplicationContext() { 47 | return ctx; 48 | 49 | } 50 | 51 | @Override 52 | public int size() { 53 | return ctx.getBeanDefinitionCount() + super.size(); 54 | } 55 | 56 | @Override 57 | public boolean isEmpty() { 58 | return super.isEmpty() && ctx.getBeanDefinitionCount() == 0; 59 | } 60 | 61 | @Override 62 | public boolean containsKey(Object key) { 63 | if (key instanceof String && ctx.containsBean((String)key)) { 64 | return true; 65 | } else { 66 | return super.containsKey(key); 67 | } 68 | 69 | } 70 | 71 | @Override 72 | public Object get(Object key) { 73 | if (key instanceof String && ctx.containsBean((String)key)) { 74 | return ctx.getBean((String)key); 75 | } else { 76 | return super.get(key); 77 | } 78 | } 79 | 80 | 81 | } 82 | -------------------------------------------------------------------------------- /bootloader/src/main/java/net/matlux/ReplStartup.java: -------------------------------------------------------------------------------- 1 | package net.matlux; 2 | 3 | 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | import clojure.lang.Symbol; 9 | import clojure.lang.Var; 10 | import clojure.lang.RT; 11 | /** 12 | * Hello world! 13 | * 14 | */ 15 | public class ReplStartup 16 | { 17 | 18 | private Map objMap = new HashMap(); 19 | static public ReplStartup instance=null; 20 | 21 | final static public int DEFAULT_PORT=1112; 22 | final static private Var USE = RT.var("clojure.core", "use"); 23 | final static private Symbol SERVER_SOCKET_NS = Symbol.intern("server.socket"); 24 | final static private Var CREATE_REPL_SERVER = RT.var("server.socket","create-repl-server"); 25 | 26 | ReplStartup(int port) { 27 | USE.invoke(SERVER_SOCKET_NS); 28 | CREATE_REPL_SERVER.invoke(port); 29 | instance=this; 30 | } 31 | 32 | public static void main(String[] args) throws Exception { 33 | int port=DEFAULT_PORT; 34 | if(args.length > 0) { 35 | port = Integer.parseInt(args[0]); 36 | } 37 | 38 | new ReplStartup(port); 39 | } 40 | 41 | public Object getObj(String key) { 42 | return objMap.get(key); 43 | } 44 | public void setObjMap(Map objMap) { 45 | this.objMap = objMap; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /bootloader/src/test/clojure/cl_java_introspector/test_app.clj: -------------------------------------------------------------------------------- 1 | (ns cl-java-introspector.test-app 2 | (:require [clojure.test :refer :all] 3 | [cl-java-introspector.core :refer :all] 4 | [cl-java-introspector.client-example :refer [remote-execute]]) 5 | (:import [net.matlux NreplServerSpring] 6 | [net.matlux NreplServer] 7 | [net.matlux.testobjects Employee] 8 | [net.matlux.testobjects Address] 9 | [net.matlux.fixtures Fixtures] 10 | )) 11 | 12 | 13 | (def test1 (str "(import '(net.matlux NreplServerSpring)) 14 | (import '(net.matlux NreplServer)) 15 | (use 'cl-java-introspector.spring) 16 | (use 'cl-java-introspector.core) 17 | (import 'net.matlux.testobjects.Address) 18 | (use 'clojure.reflect 'clojure.pprint 'clojure.java.javadoc) 19 | (use 'me.raynes.fs) 20 | (get-beans) 21 | (get-objs) 22 | (def employee1 (get-obj \"employee1\")) 23 | (.getFirstname employee1) 24 | (->> employee1 .getAddress .getCity) 25 | (.setAddress employee1 (proxy [Address] [\"1 Madison Square\",\"SW2\",\"NY\"] (getStreet [] \"1 Madison Square\") (getCity [] \"" Fixtures/CITY1 "\"))) 26 | (->> employee1 .getAddress .getCity)")) 27 | 28 | (def fixture-test1-result (list 'net.matlux.NreplServerSpring 'net.matlux.NreplServer nil nil 'net.matlux.testobjects.Address nil nil ["employee1" "a_test_obj"] '(var user/employee1) Fixtures/EMPLOYEE_FNAME1 Fixtures/STREET1 nil Fixtures/CITY1)) 29 | (def fixture-test1-result-dropped (list ["employee1" "a_test_obj"] '(var user/employee1) Fixtures/EMPLOYEE_FNAME1 Fixtures/STREET1 nil Fixtures/CITY1)) 30 | 31 | (def test2 (str "(import '(net.matlux NreplServerSpring)) 32 | (import '(net.matlux NreplServer)) 33 | (use 'cl-java-introspector.spring) 34 | (use 'cl-java-introspector.core) 35 | (import 'net.matlux.testobjects.Address) 36 | (use 'clojure.reflect 'clojure.pprint 'clojure.java.javadoc) 37 | (use 'me.raynes.fs) 38 | (get-beans) 39 | (get-objs) 40 | (def employees (->> (get-obj \"department\") .getEmployees (into []) (map #(vector (keyword (.getFirstname %)) %)) (into {}))) 41 | (->> (:Mick employees) .getAddress .getCity) 42 | (def new-addr (proxy [Address] [\"1 Madison Square\",\"SW2\",\"NY\"] (getStreet [] \"1 Madison Square\") (getCity [] \"NY\"))) 43 | (.getCity new-addr) 44 | (.setAddress (:Mick employees) new-addr) 45 | (->> (:Mick employees) .getAddress .getCity)")) 46 | 47 | (def fixture-test2-result (vector 'net.matlux.NreplServerSpring 'net.matlux.NreplServer nil nil 'net.matlux.testobjects.Address nil nil ["address1" "address2" "address3" "employee1" "employee2" "employee3" "department" "repl"] [] '(var user/employees) "1 Madison Square" '(var user/new-addr) "NY" nil "NY")) 48 | (def fixture-test2-result-7dropped (vector ["address1" "address2" "address3" "employee1" "employee2" "employee3" "department" "repl"] [] '(var user/employees) "1 Madison Square" '(var user/new-addr) "NY" nil "NY")) 49 | 50 | 51 | (defn run-remote-test-code1 [port code] 52 | (let [server (NreplServer. port) 53 | _ (.put server "a_test_obj" "this is a test String.") 54 | original-emp (Employee. Fixtures/EMPLOYEE_FNAME1 Fixtures/EMPLOYEE_LNAME1 (Address. Fixtures/STREET1 Fixtures/ZIPCODE1 Fixtures/CITY1)) 55 | _ (.put server "employee1" original-emp) 56 | res (remote-execute "localhost" 1114 code)] 57 | (.stop server) 58 | (.unregisterMBean server) 59 | (drop 7 res))) 60 | 61 | (deftest test-app-with-NreplServer 62 | (testing "test" 63 | (is (= (run-remote-test-code1 1114 test1) 64 | fixture-test1-result-dropped)))) 65 | 66 | ;;(deftest test-app-with-NreplServerSpring 67 | ;; (testing "test" 68 | ;; (is (= (let [server (NreplServer. 1113) 69 | ;; _ (.put server "a_test_obj" "this is a test String.") 70 | ;; original-emp (Employee. Fixtures/EMPLOYEE_FNAME1 Fixtures/EMPLOYEE_LNAME1 (Address. Fixtures/STREET1 Fixtures/ZIPCODE1 Fixtures/CITY1)) 71 | ;; _ (.put server "employee1" original-emp) 72 | ;; res (remote-execute "localhost" 1113 test1)] 73 | ;; (.stop server) 74 | ;; (.unregisterMBean server) 75 | ;; (drop 7 res)) 76 | ;; (list ["employee1" "a_test_obj"] '(var user/employee1) Fixtures/EMPLOYEE_FNAME1 Fixtures/STREET1 nil Fixtures/CITY1))))) 77 | -------------------------------------------------------------------------------- /bootloader/src/test/java/net/matlux/AppTest.java: -------------------------------------------------------------------------------- 1 | package net.matlux; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | import org.junit.After; 8 | import org.junit.AfterClass; 9 | import org.junit.Before; 10 | import org.junit.BeforeClass; 11 | import org.junit.Test; 12 | import org.springframework.context.support.ClassPathXmlApplicationContext; 13 | 14 | import clojure.lang.RT; 15 | import clojure.lang.Symbol; 16 | import clojure.lang.Var; 17 | import net.matlux.NreplServer; 18 | import net.matlux.testobjects.Address; 19 | import net.matlux.testobjects.Employee; 20 | import static net.matlux.fixtures.Fixtures.*; 21 | import static org.junit.Assert.*; 22 | /** 23 | * Unit test for simple App. 24 | */ 25 | public class AppTest 26 | { 27 | 28 | @BeforeClass 29 | public static void oneTimeSetUp() { 30 | // one-time initialization code 31 | USE.invoke(REPL_CLIENT_NS); 32 | USE.invoke(TEST_APP_NS); 33 | USE.invoke(DATA_NS); 34 | System.out.println("@BeforeClass - oneTimeSetUp"); 35 | } 36 | 37 | @AfterClass 38 | public static void oneTimeTearDown() { 39 | // one-time cleanup code 40 | System.out.println("@AfterClass - oneTimeTearDown"); 41 | } 42 | 43 | @Before 44 | public void setUp() { 45 | System.out.println("@Before - setUp" + MBeanTest.class.getSimpleName()); 46 | } 47 | 48 | @After 49 | public void tearDown() { 50 | System.out.println("@After - tearDown" + MBeanTest.class.getSimpleName()); 51 | } 52 | 53 | final static private Var USE = RT.var("clojure.core", "use"); 54 | final static private Var DROP = RT.var("clojure.core", "drop"); 55 | final static private Var FIRST = RT.var("clojure.core", "first"); 56 | final static private Var REST = RT.var("clojure.core", "rest"); 57 | final static private Var TYPE = RT.var("clojure.core", "type"); 58 | final static private Var DIFF = RT.var("clojure.data", "diff"); 59 | final static private Symbol REPL_CLIENT_NS = Symbol.intern("cl-java-introspector.client-example"); 60 | final static private Symbol TEST_APP_NS = Symbol.intern("cl-java-introspector.test-app"); 61 | final static private Symbol DATA_NS = Symbol.intern("clojure.data"); 62 | final static private Var REMOTE_EXECUTE = RT.var("cl-java-introspector.client-example", "remote-execute"); 63 | final static private Var REMOTE_CODE_FIXTURE = RT.var("cl-java-introspector.test-app", "test1"); 64 | final static private Var REMOTE_CODE_RESULT_FIXTURE = RT.var("cl-java-introspector.test-app", "fixture-test1-result"); 65 | final static private Var REMOTE_CODE_FIXTURE2 = RT.var("cl-java-introspector.test-app", "test2"); 66 | final static private Var REMOTE_CODE_RESULT_FIXTURE2 = RT.var("cl-java-introspector.test-app", "fixture-test2-result"); 67 | 68 | 69 | 70 | private Object remoteConnect2ReplAndRunSomeCommands(Var codefixture, int port) { 71 | return REMOTE_EXECUTE.invoke("localhost", port, codefixture.deref()); 72 | } 73 | 74 | private void canSuccessfullyRunRemoteCommands(Var codeFixture,Var expectedResult, int port) { 75 | Object result = remoteConnect2ReplAndRunSomeCommands(codeFixture, port); 76 | System.out.println("testStartApp result=" + result); 77 | System.out.println("testStartApp expected=" + expectedResult.deref()); 78 | System.out.println("diff=" + DIFF.invoke(result, expectedResult.deref())); 79 | 80 | assertTrue(result.equals(expectedResult.deref())); 81 | //assertTrue(FIRST.invoke(result).equals(FIRST.invoke(expectedResult.deref()))); 82 | } 83 | private void setupFixtureDataOnServer(NreplServer server) { 84 | server.put("a_test_obj", "this is a test String."); 85 | System.out.println("Added a_test_obj to server"); 86 | Employee originalEmployee = new Employee(EMPLOYEE_FNAME1,EMPLOYEE_LNAME1,new Address(STREET1, ZIPCODE1, CITY1) ); 87 | server.put("employee1", originalEmployee); 88 | System.out.println("Added employe1 to server"); 89 | } 90 | 91 | private void connectionOnPortRefused(int port) { 92 | assertTrue(remoteConnect2ReplAndRunSomeCommands(REMOTE_CODE_FIXTURE, port).equals("cannot connect")); 93 | } 94 | 95 | 96 | @Test 97 | public void testStartApp() 98 | { 99 | NreplServer server = new NreplServer(1112,false,false,true,false); 100 | setupFixtureDataOnServer(server); 101 | connectionOnPortRefused(1112); 102 | server.start(); 103 | canSuccessfullyRunRemoteCommands(REMOTE_CODE_FIXTURE, REMOTE_CODE_RESULT_FIXTURE, 1112); 104 | server.stop(); 105 | } 106 | @Test 107 | public void testSpringApp() 108 | { 109 | ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring/server-test.xml"); 110 | canSuccessfullyRunRemoteCommands(REMOTE_CODE_FIXTURE2, REMOTE_CODE_RESULT_FIXTURE2, 1112); 111 | NreplServerSpring server = (NreplServerSpring)context.getBean("repl"); 112 | 113 | server.stop(); 114 | server.unregisterMBean(); 115 | context.close(); 116 | } 117 | 118 | @Test 119 | public void testAutoStartStopApp() 120 | { 121 | NreplServer server = new NreplServer(1112,true,false,true,false); 122 | setupFixtureDataOnServer(server); 123 | 124 | canSuccessfullyRunRemoteCommands(REMOTE_CODE_FIXTURE, REMOTE_CODE_RESULT_FIXTURE, 1112); 125 | 126 | server.stop(); 127 | connectionOnPortRefused(1112); 128 | } 129 | 130 | @Test 131 | public void testAutoRegisterStartStopApp() 132 | { 133 | NreplServer server = new NreplServer(1112,false,true,true,false); //start server listening onto port number 134 | setupFixtureDataOnServer(server); 135 | 136 | connectionOnPortRefused(1112); 137 | 138 | server.start(); 139 | canSuccessfullyRunRemoteCommands(REMOTE_CODE_FIXTURE, REMOTE_CODE_RESULT_FIXTURE, 1112); 140 | 141 | server.stop(); 142 | server.unregisterMBean(); 143 | 144 | connectionOnPortRefused(1112); 145 | } 146 | 147 | @Test 148 | public void testRegisterStartStopApp() 149 | { 150 | NreplServer server = new NreplServer(1112,false,false,true,false); //start server listening onto port number 151 | try { 152 | server.registerMBean(); 153 | setupFixtureDataOnServer(server); 154 | 155 | connectionOnPortRefused(1112); 156 | 157 | server.start(); 158 | canSuccessfullyRunRemoteCommands(REMOTE_CODE_FIXTURE, REMOTE_CODE_RESULT_FIXTURE, 1112); 159 | 160 | } finally { 161 | 162 | server.stop(); 163 | server.unregisterMBean(); 164 | 165 | } 166 | connectionOnPortRefused(1112); 167 | } 168 | 169 | public void testSamePortStartTwice() 170 | { 171 | NreplServer server = new NreplServer(1113,true,false,true,false); //start server listening onto port number 172 | NreplServer server2 = new NreplServer(1113,true,false,true,false); //start server listening onto port number 173 | 174 | server.stop(); 175 | server2.stop(); 176 | } 177 | @Test 178 | public void testStartTwice() 179 | { 180 | NreplServer server = new NreplServer(1113); //start server listening onto port number 181 | assertEquals(1113, server.getPort()); 182 | server.start(); 183 | server.stop(); 184 | server.unregisterMBean(); 185 | } 186 | @Test 187 | public void testStopTwice() 188 | { 189 | NreplServer server = new NreplServer(1113); //start server listening onto port number 190 | assertEquals(1113, server.getPort()); 191 | server.stop(); 192 | server.stop(); 193 | server.unregisterMBean(); 194 | } 195 | 196 | final int NB_THREADS = 4; 197 | final int ITERATIONS = 1000; 198 | private static final int PORT_NUMBER = 1114; 199 | 200 | 201 | @Test 202 | public void testStartStopServerThreadSafety1() throws InterruptedException 203 | { //todo: start multiple servers from different threads 204 | final NreplServer server = new NreplServer(PORT_NUMBER,true,false,true,true);//start server listening onto port number 205 | assertEquals(PORT_NUMBER, server.getPort()); 206 | 207 | setupFixtureDataOnServer(server); 208 | 209 | ExecutorService es = Executors.newFixedThreadPool(NB_THREADS); 210 | 211 | 212 | for(int i=0; i employees = new LinkedList(); 9 | private String name; 10 | private long id; 11 | 12 | public Department(String name,long id) { 13 | this.name = name; 14 | this.id = id; 15 | } 16 | 17 | public String getName() { 18 | return name; 19 | } 20 | public void setName(String name) { 21 | this.name = name; 22 | } 23 | public List getEmployees() { 24 | return employees; 25 | } 26 | public void setEmployees(List employees) { 27 | this.employees = employees; 28 | } 29 | 30 | public void add(Employee employee) { 31 | employees.add(employee); 32 | 33 | } 34 | 35 | 36 | 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /bootloader/src/test/java/net/matlux/testobjects/Employee.java: -------------------------------------------------------------------------------- 1 | package net.matlux.testobjects; 2 | 3 | public class Employee { 4 | 5 | private String firstname; 6 | private String lastname; 7 | 8 | private Address address; 9 | 10 | public Employee(String firstname, String lastname, Address address) { 11 | this.firstname = firstname; 12 | this.lastname = lastname; 13 | this.setAddress(address); 14 | } 15 | 16 | public String getFirstname() { 17 | return firstname; 18 | } 19 | 20 | public Address getAddress() { 21 | return address; 22 | } 23 | 24 | public void setAddress(Address address) { 25 | this.address = address; 26 | } 27 | public String toString() { 28 | return firstname + " " +lastname; 29 | } 30 | 31 | 32 | @Override public boolean equals(Object other) { 33 | boolean result = false; 34 | if (other instanceof Employee) { 35 | Employee that = (Employee) other; 36 | result = (this.firstname.equals(that.firstname) && 37 | this.lastname.equals(that.lastname) && 38 | this.address.equals(that.address) && 39 | super.equals(that)); 40 | } 41 | return result; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /bootloader/src/test/resources/spring/server-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | 25 | 27 | 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 37 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /clj.sh: -------------------------------------------------------------------------------- 1 | REPO=~/.m2/repository 2 | 3 | 4 | CLOJURE=$CLASSPATH:$REPO/org/clojure/clojure/1.4.0/clojure-1.4.0.jar 5 | CLOJURE=$CLOJURE:$REPO/org/clojure/tools.nrepl/0.2.1/tools.nrepl-0.2.1.jar 6 | CLOJURE=$CLOJURE:$REPO/org/springframework/spring-web/3.0.4.RELEASE/spring-web-3.0.4.RELEASE.jar 7 | CLOJURE=$CLOJURE:$REPO/org/springframework/spring-context/3.0.4.RELEASE/spring-context-3.0.4.RELEASE.jar 8 | CLOJURE=$CLOJURE:$REPO/org/springframework/spring-core/3.0.4.RELEASE/spring-core-3.0.4.RELEASE.jar 9 | CLOJURE=$CLOJURE:$REPO/org/slf4j/slf4j-api/1.6.3/slf4j-api-1.6.3.jar 10 | CLOJURE=$CLOJURE:./src/test/clojure 11 | CLOJURE=$CLOJURE:target/repl-bootloader-1.0-SNAPSHOT.jar 12 | CLOJURE=$CLOJURE:${PWD} 13 | 14 | if [ "$#" -eq 0 ]; then 15 | #java -cp $CLOJURE clojure.main --repl 16 | exec rlwrap --remember -c -b "$breakchars" \ 17 | -f "$HOME"/.clj_completions \ 18 | java -cp "$CLOJURE" clojure.main 19 | else 20 | #java -cp $CLOJURE clojure.main "$@" 21 | exec java -cp "$CLOJURE" clojure.main "$@" 22 | fi 23 | -------------------------------------------------------------------------------- /examples/SpringMVC/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.mkyong.common 5 | SpringMVC 6 | war 7 | 1.0-SNAPSHOT 8 | SpringMVC Maven Webapp 9 | http://maven.apache.org 10 | 11 | 12 | 3.0.5.RELEASE 13 | 14 | 15 | 16 | 17 | net.matlux 18 | jvm-breakglass 19 | 0.0.7 20 | 21 | 22 | 23 | 24 | org.springframework 25 | spring-core 26 | ${spring.version} 27 | 28 | 29 | 30 | org.springframework 31 | spring-web 32 | ${spring.version} 33 | 34 | 35 | 36 | org.springframework 37 | spring-webmvc 38 | ${spring.version} 39 | 40 | 41 | 42 | 43 | 44 | SpringMVC 45 | 46 | 47 | maven-compiler-plugin 48 | 49 | 1.6 50 | 1.6 51 | 52 | 53 | 54 | 55 | 56 | 57 | clojars.org 58 | http://clojars.org/repo 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /examples/SpringMVC/presentation.md: -------------------------------------------------------------------------------- 1 | 2 | ## Presentation check list 3 | 4 | * redeploy war file: 5 | 6 | cd /datashare/applications/apache-tomcat-7.0.53/bin 7 | ./shutdown.sh ;rm -r ../webapps/SpringMVC* ; cp /Users/mathieu/datashare/mgauthron/clojure/jvm-breakglass/examples/SpringMVC/target/*.war ../webapps/ ; ./startup.sh 8 | 9 | * open eclipse on Address class 10 | * start emacs 11 | 12 | cd ~/datashare/mgauthron/clojure/jvm-breakglass 13 | emacs bootloader/src/main/clojure/cl_java_introspector/examples.clj 14 | 15 | * start cider on port 1112 16 | * increase font C-x C-+ 17 | * preload namespaces 18 | * test (System/getProperties) 19 | -------------------------------------------------------------------------------- /examples/SpringMVC/src/main/java/net/matlux/controller/ReportController.java: -------------------------------------------------------------------------------- 1 | package net.matlux.controller; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.Comparator; 6 | import java.util.List; 7 | 8 | import net.matlux.NreplServer; 9 | import net.matlux.testobjects.Department; 10 | import net.matlux.testobjects.Employee; 11 | 12 | import org.springframework.stereotype.Controller; 13 | import org.springframework.ui.ModelMap; 14 | import org.springframework.web.bind.annotation.PathVariable; 15 | import org.springframework.web.bind.annotation.RequestMapping; 16 | import org.springframework.web.bind.annotation.RequestMethod; 17 | 18 | @Controller 19 | @RequestMapping("/city") 20 | public class ReportController { 21 | 22 | @RequestMapping(value = "{name}", method = RequestMethod.GET) 23 | public String getEmployeesByCity(@PathVariable String name, ModelMap model) { 24 | //String name = "NY"; 25 | Department dep = (Department)NreplServer.instance.get("department"); 26 | List emps = dep.getEmployees(); 27 | Collections.sort(emps,new Comparator() { 28 | @Override 29 | public int compare(Object o1, Object o2) { 30 | Employee e1 = (Employee)o1; 31 | Employee e2 = (Employee)o2; 32 | return e1.getAddress().getCity().compareTo(e2.getAddress().getCity()); 33 | } 34 | 35 | }); 36 | List empsRes = new ArrayList(); 37 | for(Employee e:emps) { 38 | if(name.equals("all")) { 39 | empsRes.add(e); 40 | } else if(name.equalsIgnoreCase(e.getAddress().getCity()) ) { 41 | empsRes.add(e); 42 | } 43 | } 44 | 45 | model.put("empsRes", empsRes); 46 | model.put("city", name); 47 | model.addAttribute("message", "Spring 3 MVC Hello World"); 48 | return "displayEmployeesByCity"; 49 | 50 | } 51 | @RequestMapping(method = RequestMethod.GET) 52 | public String getAllEmployees(ModelMap model) { 53 | String name = "all"; 54 | Department dep = (Department)NreplServer.instance.get("department"); 55 | List emps = dep.getEmployees(); 56 | Collections.sort(emps,new Comparator() { 57 | 58 | @Override 59 | public int compare(Object o1, Object o2) { 60 | Employee e1 = (Employee)o1; 61 | Employee e2 = (Employee)o2; 62 | return e1.getAddress().getCity().compareTo(e2.getAddress().getCity()); 63 | } 64 | 65 | }); 66 | List empsRes = new ArrayList(); 67 | for(Employee e:emps) { 68 | empsRes.add(e); 69 | } 70 | 71 | model.put("empsRes", empsRes); 72 | model.put("city", name); 73 | return "displayAllEmployees"; 74 | 75 | } 76 | 77 | } -------------------------------------------------------------------------------- /examples/SpringMVC/src/main/java/net/matlux/testobjects/Address.java: -------------------------------------------------------------------------------- 1 | package net.matlux.testobjects; 2 | 3 | public class Address { 4 | 5 | private String street; 6 | private String zipcode; 7 | private String city; 8 | 9 | public Address(String street, String zipcode, String city) { 10 | this.street = street; 11 | this.zipcode = zipcode; 12 | this.city = city; 13 | } 14 | 15 | public String getStreet() { 16 | return city; 17 | } 18 | 19 | public String getCity() { 20 | return street; 21 | } 22 | 23 | public String getZipcode() { 24 | return zipcode; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /examples/SpringMVC/src/main/java/net/matlux/testobjects/Department.java: -------------------------------------------------------------------------------- 1 | package net.matlux.testobjects; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | public class Department { 7 | 8 | private List employees = new LinkedList(); 9 | private String name; 10 | private long id; 11 | 12 | public Department(String name,long id) { 13 | this.name = name; 14 | this.id = id; 15 | } 16 | 17 | public String getName() { 18 | return name; 19 | } 20 | public void setName(String name) { 21 | this.name = name; 22 | } 23 | public List getEmployees() { 24 | return employees; 25 | } 26 | public void setEmployees(List employees) { 27 | this.employees = employees; 28 | } 29 | 30 | public void add(Employee employee) { 31 | employees.add(employee); 32 | 33 | } 34 | 35 | 36 | 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /examples/SpringMVC/src/main/java/net/matlux/testobjects/Employee.java: -------------------------------------------------------------------------------- 1 | package net.matlux.testobjects; 2 | 3 | public class Employee { 4 | 5 | private String firstname; 6 | private String lastname; 7 | 8 | private Address address; 9 | 10 | public Employee(String firstname, String lastname, Address address) { 11 | this.firstname = firstname; 12 | this.lastname = lastname; 13 | this.setAddress(address); 14 | } 15 | 16 | public String getFirstname() { 17 | return firstname; 18 | } 19 | 20 | public Address getAddress() { 21 | return address; 22 | } 23 | 24 | public void setAddress(Address address) { 25 | this.address = address; 26 | } 27 | public String toString() { 28 | return firstname + " " +lastname; 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /examples/SpringMVC/src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 14 | 15 | /WEB-INF/pages/ 16 | 17 | 18 | .jsp 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 41 | 42 | 43 | 44 | 45 | 47 | 48 | 49 | 50 | 51 | 53 | 54 | 55 | 56 | 57 | 58 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /examples/SpringMVC/src/main/webapp/WEB-INF/pages/displayAllEmployees.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 | 10 |

Message from our president:

11 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate. 12 |

May the Closure be with you! 13 |

Lots of hugs, 14 |

Bruce 15 |

16 |
17 |

Very Important Enterprise Application

18 |
19 |
20 |

List of All Employees:

21 |

${empsRes}

22 | 23 |

Select a report:


24 |
25 | 26 |
27 |
28 | 29 |
30 | 31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /examples/SpringMVC/src/main/webapp/WEB-INF/pages/displayEmployeesByCity.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 |

Message from our president:

10 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate. 11 |

May the Closure be with you! 12 |

Lots of hugs, 13 |

Bruce 14 |

15 |
16 |

Very Important Enterprise Application

17 |
18 |
19 |

Report: Employees living in ${city}

20 |

List : ${empsRes}

21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /examples/SpringMVC/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | Spring Web MVC Application 7 | 8 | 9 | mvc-dispatcher 10 | org.springframework.web.servlet.DispatcherServlet 11 | 1 12 | 13 | 14 | 15 | mvc-dispatcher 16 | / 17 | 18 | 19 | 20 | default 21 | *.css 22 | 23 | 24 | default 25 | *.js 26 | 27 | 28 | default 29 | *.gif 30 | 31 | 32 | default 33 | *.jpg 34 | 35 | 36 | default 37 | *.png 38 | 39 | 40 | 41 | contextConfigLocation 42 | /WEB-INF/mvc-dispatcher-servlet.xml 43 | 44 | 45 | 46 | org.springframework.web.context.ContextLoaderListener 47 | 48 | 49 | -------------------------------------------------------------------------------- /examples/SpringMVC/src/main/webapp/css/mystyle.css: -------------------------------------------------------------------------------- 1 | .title { 2 | float: center; 3 | width: 79%; 4 | margin-left: 10%; 5 | } 6 | .left { 7 | float: left; 8 | width: 69%; 9 | margin-left: 10%; 10 | } 11 | .left img { 12 | float: right; 13 | } 14 | .right { 15 | float: right; 16 | width: 20%; 17 | } 18 | input.reportbutton { 19 | width: 8em; 20 | height: 5em; 21 | font-size: 5em; 22 | } -------------------------------------------------------------------------------- /examples/SpringMVC/src/main/webapp/images/bruce.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matlux/jvm-breakglass/e6d107ddd8a686bc27ed46dd803c53b16d98f389/examples/SpringMVC/src/main/webapp/images/bruce.jpg -------------------------------------------------------------------------------- /examples/SpringMVCrest/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.mkyong.common 5 | SpringMVCjson 6 | war 7 | 1.0-SNAPSHOT 8 | SpringMVC Json Webapp 9 | http://maven.apache.org 10 | 11 | 12 | 3.2.2.RELEASE 13 | 1.9.10 14 | 1.6 15 | 16 | 17 | 18 | 19 | net.matlux 20 | jvm-breakglass 21 | 0.0.6 22 | 23 | 24 | 25 | org.springframework 26 | spring-core 27 | ${spring.version} 28 | 29 | 30 | 31 | org.springframework 32 | spring-web 33 | ${spring.version} 34 | 35 | 36 | 37 | org.springframework 38 | spring-webmvc 39 | ${spring.version} 40 | 41 | 42 | 43 | 44 | org.codehaus.jackson 45 | jackson-mapper-asl 46 | ${jackson.version} 47 | 48 | 49 | 50 | 51 | 52 | SpringMVC 53 | 54 | 55 | org.apache.maven.plugins 56 | maven-eclipse-plugin 57 | 2.9 58 | 59 | true 60 | false 61 | 2.0 62 | 63 | 64 | 65 | org.apache.maven.plugins 66 | maven-compiler-plugin 67 | 2.3.2 68 | 69 | ${jdk.version} 70 | ${jdk.version} 71 | 72 | 73 | 74 | 75 | 76 | 77 | clojars.org 78 | http://clojars.org/repo 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /examples/SpringMVCrest/src/main/java/com/mkyong/common/controller/JSONController.java: -------------------------------------------------------------------------------- 1 | package com.mkyong.common.controller; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.Comparator; 6 | import java.util.List; 7 | 8 | import net.matlux.NreplServer; 9 | import net.matlux.testobjects.Department; 10 | import net.matlux.testobjects.Employee; 11 | 12 | import org.springframework.stereotype.Controller; 13 | import org.springframework.web.bind.annotation.PathVariable; 14 | import org.springframework.web.bind.annotation.RequestMapping; 15 | import org.springframework.web.bind.annotation.RequestMethod; 16 | import org.springframework.web.bind.annotation.ResponseBody; 17 | 18 | 19 | @Controller 20 | @RequestMapping("/city") 21 | public class JSONController { 22 | 23 | @SuppressWarnings("unchecked") 24 | @RequestMapping(value = "{name}", method = RequestMethod.GET) 25 | public @ResponseBody 26 | List getEmployeeFromNY(@PathVariable String name) { 27 | 28 | Department dep = (Department)NreplServer.instance.get("department"); 29 | List emps = dep.getEmployees(); 30 | Collections.sort(emps,new Comparator() { 31 | 32 | @Override 33 | public int compare(Object o1, Object o2) { 34 | Employee e1 = (Employee)o1; 35 | Employee e2 = (Employee)o2; 36 | return e1.getAddress().getCity().compareTo(e2.getAddress().getCity()); 37 | } 38 | 39 | }); 40 | List empsRes = new ArrayList(); 41 | for(Employee e:emps) { 42 | if(name.equals("all")) { 43 | empsRes.add(e); 44 | } else if(name.equalsIgnoreCase(e.getAddress().getCity()) ) { 45 | empsRes.add(e); 46 | } 47 | 48 | } 49 | return empsRes; 50 | 51 | 52 | } 53 | 54 | } -------------------------------------------------------------------------------- /examples/SpringMVCrest/src/main/java/com/mkyong/common/model/Shop.java: -------------------------------------------------------------------------------- 1 | package com.mkyong.common.model; 2 | 3 | public class Shop { 4 | 5 | String name; 6 | 7 | String staffName[]; 8 | public String getName() { 9 | return name; 10 | } 11 | public void setName(String name) { 12 | this.name = name; 13 | } 14 | public String[] getStaffName() { 15 | return staffName; 16 | } 17 | public void setStaffName(String[] staffName) { 18 | this.staffName = staffName; 19 | } 20 | public Shop() { 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /examples/SpringMVCrest/src/main/java/net/matlux/testobjects/Address.java: -------------------------------------------------------------------------------- 1 | package net.matlux.testobjects; 2 | 3 | public class Address { 4 | 5 | private String street; 6 | private String zipcode; 7 | private String city; 8 | 9 | public Address(String street, String zipcode, String city) { 10 | this.street = street; 11 | this.zipcode = zipcode; 12 | this.city = city; 13 | } 14 | 15 | public String getStreet() { 16 | return city; 17 | } 18 | 19 | public String getCity() { 20 | return street; 21 | } 22 | 23 | public String getZipcode() { 24 | return zipcode; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /examples/SpringMVCrest/src/main/java/net/matlux/testobjects/Department.java: -------------------------------------------------------------------------------- 1 | package net.matlux.testobjects; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | public class Department { 7 | 8 | private List employees = new LinkedList(); 9 | private String name; 10 | private long id; 11 | 12 | public Department(String name,long id) { 13 | this.name = name; 14 | this.id = id; 15 | } 16 | 17 | public String getName() { 18 | return name; 19 | } 20 | public void setName(String name) { 21 | this.name = name; 22 | } 23 | public List getEmployees() { 24 | return employees; 25 | } 26 | public void setEmployees(List employees) { 27 | this.employees = employees; 28 | } 29 | 30 | public void add(Employee employee) { 31 | employees.add(employee); 32 | 33 | } 34 | 35 | 36 | 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /examples/SpringMVCrest/src/main/java/net/matlux/testobjects/Employee.java: -------------------------------------------------------------------------------- 1 | package net.matlux.testobjects; 2 | 3 | public class Employee { 4 | 5 | private String firstname; 6 | private String lastname; 7 | 8 | private Address address; 9 | 10 | public Employee(String firstname, String lastname, Address address) { 11 | this.firstname = firstname; 12 | this.lastname = lastname; 13 | this.setAddress(address); 14 | } 15 | 16 | public String getFirstname() { 17 | return firstname; 18 | } 19 | 20 | public Address getAddress() { 21 | return address; 22 | } 23 | 24 | public void setAddress(Address address) { 25 | this.address = address; 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /examples/SpringMVCrest/src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 30 | 31 | 32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 42 | 43 | 44 | 45 | 46 | 48 | 49 | 50 | 51 | 52 | 53 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /examples/SpringMVCrest/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | Spring Web MVC Application 7 | 8 | 9 | mvc-dispatcher 10 | org.springframework.web.servlet.DispatcherServlet 11 | 1 12 | 13 | 14 | 15 | mvc-dispatcher 16 | /rest/* 17 | 18 | 19 | 20 | contextConfigLocation 21 | /WEB-INF/mvc-dispatcher-servlet.xml 22 | 23 | 24 | 25 | org.springframework.web.context.ContextLoaderListener 26 | 27 | 28 | -------------------------------------------------------------------------------- /examples/server-no-spring/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | net.matlux 5 | server-no-spring-test 6 | jar 7 | 1.0-SNAPSHOT 8 | http://maven.apache.org 9 | 10 | 11 | 12 | maven-compiler-plugin 13 | 2.3.2 14 | 15 | 1.7 16 | 1.7 17 | 18 | 19 | 20 | com.theoryinpractise 21 | clojure-maven-plugin 22 | 1.3.10 23 | 24 | 25 | compile 26 | compile 27 | 28 | compile 29 | 30 | 31 | 32 | test 33 | test 34 | 35 | test 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | src/main/clojure 44 | 45 | 46 | src/main/resources 47 | 48 | 49 | 50 | 51 | 52 | net.matlux 53 | jvm-breakglass 54 | 0.0.7 55 | 56 | 57 | junit 58 | junit 59 | 3.8.1 60 | test 61 | 62 | 63 | 64 | 65 | clojars.org 66 | http://clojars.org/repo 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /examples/server-no-spring/src/main/java/net/matlux/testobjects/Address.java: -------------------------------------------------------------------------------- 1 | package net.matlux.testobjects; 2 | 3 | public class Address { 4 | 5 | private String street; 6 | private String zipcode; 7 | private String city; 8 | 9 | public Address(String street, String zipcode, String city) { 10 | this.street = street; 11 | this.zipcode = zipcode; 12 | this.city = city; 13 | } 14 | 15 | public String getStreet() { 16 | return city; 17 | } 18 | 19 | public String getCity() { 20 | return street; 21 | } 22 | 23 | public String getZipcode() { 24 | return zipcode; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /examples/server-no-spring/src/main/java/net/matlux/testobjects/Department.java: -------------------------------------------------------------------------------- 1 | package net.matlux.testobjects; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | public class Department { 7 | 8 | private List employees = new LinkedList(); 9 | private String name; 10 | private long id; 11 | 12 | public Department(String name,long id) { 13 | this.name = name; 14 | this.id = id; 15 | } 16 | 17 | public String getName() { 18 | return name; 19 | } 20 | public void setName(String name) { 21 | this.name = name; 22 | } 23 | public List getEmployees() { 24 | return employees; 25 | } 26 | public void setEmployees(List employees) { 27 | this.employees = employees; 28 | } 29 | 30 | public void add(Employee employee) { 31 | employees.add(employee); 32 | 33 | } 34 | 35 | 36 | 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /examples/server-no-spring/src/main/java/net/matlux/testobjects/Employee.java: -------------------------------------------------------------------------------- 1 | package net.matlux.testobjects; 2 | 3 | public class Employee { 4 | 5 | private String firstname; 6 | private String lastname; 7 | 8 | private Address address; 9 | 10 | public Employee(String firstname, String lastname, Address address) { 11 | this.firstname = firstname; 12 | this.lastname = lastname; 13 | this.setAddress(address); 14 | } 15 | 16 | public String getFirstname() { 17 | return firstname; 18 | } 19 | 20 | public Address getAddress() { 21 | return address; 22 | } 23 | 24 | public void setAddress(Address address) { 25 | this.address = address; 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /examples/server-no-spring/src/main/java/net/matlux/testserver/SimpleServerExample.java: -------------------------------------------------------------------------------- 1 | package net.matlux.testserver; 2 | 3 | 4 | 5 | import java.util.Collections; 6 | import java.util.Comparator; 7 | import java.util.HashMap; 8 | import java.util.HashSet; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.Set; 12 | 13 | import net.matlux.NreplServer; 14 | import net.matlux.testobjects.Address; 15 | import net.matlux.testobjects.Department; 16 | import net.matlux.testobjects.Employee; 17 | 18 | 19 | /** 20 | * Hello world! 21 | * 22 | */ 23 | public class SimpleServerExample 24 | { 25 | 26 | 27 | final static public int a=1225; 28 | 29 | 30 | static public SimpleServerExample instance=null; 31 | 32 | 33 | public static void main(String[] args) throws Exception { 34 | int port=1112; 35 | if(args.length > 0) { 36 | port = Integer.parseInt(args[0]); 37 | } 38 | System.out.println("b4 new Simple nreplserver"); 39 | setupTestData(new NreplServer(port)); 40 | 41 | while (true) { 42 | 43 | Thread.sleep(2500); 44 | System.out.println("Retrieve Employees from NY or London:"); 45 | displayTransactionContent(); 46 | } 47 | 48 | } 49 | 50 | 51 | @SuppressWarnings("unchecked") 52 | private static void displayTransactionContent() { 53 | Department dep = (Department)NreplServer.instance.get("department"); 54 | List emps = dep.getEmployees(); 55 | Collections.sort(emps,new Comparator() { 56 | 57 | @Override 58 | public int compare(Object o1, Object o2) { 59 | Employee e1 = (Employee)o1; 60 | Employee e2 = (Employee)o2; 61 | return e1.getAddress().getCity().compareTo(e2.getAddress().getCity()); 62 | } 63 | 64 | }); 65 | for(Employee e:emps) { 66 | if("london".equalsIgnoreCase(e.getAddress().getCity()) || "NY".equalsIgnoreCase(e.getAddress().getCity())) { 67 | System.out.println(e.getFirstname()); 68 | } 69 | 70 | } 71 | 72 | } 73 | 74 | 75 | private static void setupTestData(NreplServer nreplServerStartup) { 76 | Map objMap = new HashMap(); 77 | // This is a nice nested object structure 78 | Department department = new Department("The Art Department",0L); 79 | department.add(new Employee("Bob","Dilan",new Address("1 Mayfair","SW1","London"))); 80 | department.add(new Employee("Mick","Jagger",new Address("1 Madison Square",null,"NY"))); 81 | objMap.put("department", department); 82 | Set myFriends = new HashSet(); 83 | myFriends.add(new Employee("Keith","Richard",new Address("2 Mayfair","SW1","Birmigham"))); 84 | myFriends.add(new Employee("Nina","Simone",new Address("1 Gerards Street","12300","Smallville"))); 85 | objMap.put("myFriends", myFriends); 86 | objMap.put("nullValue", null); 87 | System.out.println("data loaded"); 88 | 89 | 90 | objMap.put("department14", department); 91 | nreplServerStartup.setObjMap(objMap); 92 | } 93 | 94 | 95 | } 96 | -------------------------------------------------------------------------------- /examples/server-no-spring/startServer.sh: -------------------------------------------------------------------------------- 1 | REPO=~/.m2/repository 2 | 3 | 4 | CLOJURE=$CLASSPATH:$REPO/org/clojure/clojure/1.6.0/clojure-1.6.0.jar 5 | CLOJURE=$CLOJURE:$REPO/org/clojure/tools.nrepl/0.2.3/tools.nrepl-0.2.3.jar 6 | CLOJURE=$CLOJURE:./src/test 7 | CLOJURE=$CLOJURE:${PWD} 8 | CLOJURE=$CLOJURE:$REPO/me/raynes/fs/1.4.5/fs-1.4.5.jar 9 | CLOJURE=$CLOJURE:$REPO/net/matlux/jvm-breakglass/0.0.7/jvm-breakglass-0.0.7.jar 10 | CLOJURE=$CLOJURE:./target/server-no-spring-test-1.0-SNAPSHOT.jar 11 | 12 | OPTIONS=-Dcom.sun.management.jmxremote.port=9595 13 | OPTIONS=$OPTIONS\ -Dcom.sun.management.jmxremote.ssl=false 14 | OPTIONS=$OPTIONS\ -Dcom.sun.management.jmxremote.authenticate=false 15 | OPTIONS=$OPTIONS\ -Djava.rmi.server.hostname=localhost 16 | #OPTIONS=$OPTIONS\ -Djava.rmi.server.hostname=192.168.0.20 17 | 18 | java -cp "$CLOJURE" $OPTIONS net.matlux.testserver.SimpleServerExample "$@" 19 | -------------------------------------------------------------------------------- /examples/server-no-spring/stopServer.sh: -------------------------------------------------------------------------------- 1 | ps | grep java | grep -v grep | awk '{print $1}' | xargs kill -9 2 | -------------------------------------------------------------------------------- /examples/server/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | net.matlux 5 | server-test 6 | jar 7 | 1.0-SNAPSHOT 8 | spring-server-example 9 | http://maven.apache.org 10 | 11 | 12 | 13 | maven-compiler-plugin 14 | 2.3.2 15 | 16 | 1.7 17 | 1.7 18 | 19 | 20 | 21 | com.theoryinpractise 22 | clojure-maven-plugin 23 | 1.3.10 24 | 25 | 26 | compile 27 | compile 28 | 29 | compile 30 | 31 | 32 | 33 | test 34 | test 35 | 36 | test 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | src/main/clojure 45 | 46 | 47 | src/main/resources 48 | 49 | 50 | 51 | 52 | 53 | net.matlux 54 | jvm-breakglass 55 | 0.0.7 56 | 57 | 58 | org.springframework 59 | spring-web 60 | 3.0.4.RELEASE 61 | 62 | 63 | junit 64 | junit 65 | 3.8.1 66 | test 67 | 68 | 69 | 70 | 71 | clojars.org 72 | http://clojars.org/repo 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /examples/server/src/main/java/net/matlux/testobjects/Address.java: -------------------------------------------------------------------------------- 1 | package net.matlux.testobjects; 2 | 3 | public class Address { 4 | 5 | private String street; 6 | private String zipcode; 7 | private String city; 8 | 9 | public Address(String street, String zipcode, String city) { 10 | this.street = street; 11 | this.zipcode = zipcode; 12 | this.city = city; 13 | } 14 | 15 | public String getStreet() { 16 | return city; 17 | } 18 | 19 | public String getCity() { 20 | return street; 21 | } 22 | 23 | public String getZipcode() { 24 | return zipcode; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /examples/server/src/main/java/net/matlux/testobjects/Department.java: -------------------------------------------------------------------------------- 1 | package net.matlux.testobjects; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | public class Department { 7 | 8 | private List employees = new LinkedList(); 9 | private String name; 10 | private long id; 11 | 12 | public Department(String name,long id) { 13 | this.name = name; 14 | this.id = id; 15 | } 16 | 17 | public String getName() { 18 | return name; 19 | } 20 | public void setName(String name) { 21 | this.name = name; 22 | } 23 | public List getEmployees() { 24 | return employees; 25 | } 26 | public void setEmployees(List employees) { 27 | this.employees = employees; 28 | } 29 | 30 | public void add(Employee employee) { 31 | employees.add(employee); 32 | 33 | } 34 | 35 | 36 | 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /examples/server/src/main/java/net/matlux/testobjects/Employee.java: -------------------------------------------------------------------------------- 1 | package net.matlux.testobjects; 2 | 3 | public class Employee { 4 | 5 | private String firstname; 6 | private String lastname; 7 | 8 | private Address address; 9 | 10 | public Employee(String firstname, String lastname, Address address) { 11 | this.firstname = firstname; 12 | this.lastname = lastname; 13 | this.setAddress(address); 14 | } 15 | 16 | public String getFirstname() { 17 | return firstname; 18 | } 19 | 20 | public Address getAddress() { 21 | return address; 22 | } 23 | 24 | public void setAddress(Address address) { 25 | this.address = address; 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /examples/server/src/main/java/net/matlux/testserver/SpringServerExample.java: -------------------------------------------------------------------------------- 1 | package net.matlux.testserver; 2 | 3 | 4 | import java.util.Collections; 5 | import java.util.Comparator; 6 | import java.util.List; 7 | 8 | import net.matlux.NreplServer; 9 | import net.matlux.testobjects.Department; 10 | import net.matlux.testobjects.Employee; 11 | 12 | import org.springframework.beans.BeansException; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.context.ApplicationContext; 15 | import org.springframework.context.ApplicationContextAware; 16 | import org.springframework.context.support.ClassPathXmlApplicationContext; 17 | 18 | import clojure.lang.Symbol; 19 | import clojure.lang.Var; 20 | import clojure.lang.RT; 21 | /** 22 | * Hello world! 23 | * 24 | */ 25 | public class SpringServerExample implements ApplicationContextAware 26 | { 27 | 28 | 29 | static public SpringServerExample instance=null; 30 | 31 | 32 | @Autowired 33 | private ApplicationContext ctx; 34 | 35 | 36 | 37 | public static void main(String[] args) throws Exception { 38 | ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring/server-test.xml"); 39 | while (true) { 40 | 41 | Thread.sleep(2500); 42 | System.out.println("Retrieve Employees from NY or London:"); 43 | displayTransactionContent(); 44 | } 45 | } 46 | 47 | @SuppressWarnings("unchecked") 48 | private static void displayTransactionContent() { 49 | Department dep = (Department)NreplServer.instance.get("department"); 50 | List emps = dep.getEmployees(); 51 | Collections.sort(emps,new Comparator() { 52 | 53 | @Override 54 | public int compare(Object o1, Object o2) { 55 | Employee e1 = (Employee)o1; 56 | Employee e2 = (Employee)o2; 57 | return e1.getAddress().getCity().compareTo(e2.getAddress().getCity()); 58 | } 59 | 60 | }); 61 | for(Employee e:emps) { 62 | if("london".equalsIgnoreCase(e.getAddress().getCity()) || "NY".equalsIgnoreCase(e.getAddress().getCity())) { 63 | System.out.println(e.getFirstname()); 64 | } 65 | 66 | } 67 | 68 | } 69 | 70 | public Object getObj(String beanName) { 71 | return ctx.getBean(beanName); 72 | } 73 | 74 | @Override 75 | public void setApplicationContext(ApplicationContext ctx) 76 | throws BeansException { 77 | this.ctx = ctx; 78 | 79 | } 80 | 81 | public ApplicationContext getApplicationContext() { 82 | return ctx; 83 | 84 | } 85 | 86 | 87 | } 88 | -------------------------------------------------------------------------------- /examples/server/src/main/resources/spring/server-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | 25 | 27 | 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 37 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /examples/server/startSpringServer.sh: -------------------------------------------------------------------------------- 1 | REPO=~/.m2/repository 2 | 3 | 4 | CLOJURE=$CLASSPATH:$REPO/org/clojure/clojure/1.6.0/clojure-1.6.0.jar 5 | CLOJURE=$CLOJURE:$REPO/org/clojure/tools.nrepl/0.2.3/tools.nrepl-0.2.3.jar 6 | CLOJURE=$CLOJURE:$REPO/org/springframework/spring-web/3.0.4.RELEASE/spring-web-3.0.4.RELEASE.jar 7 | CLOJURE=$CLOJURE:$REPO/org/springframework/spring-context/3.0.4.RELEASE/spring-context-3.0.4.RELEASE.jar 8 | CLOJURE=$CLOJURE:$REPO/org/springframework/spring-core/3.0.4.RELEASE/spring-core-3.0.4.RELEASE.jar 9 | CLOJURE=$CLOJURE:$REPO/org/springframework/spring-beans/3.0.4.RELEASE/spring-beans-3.0.4.RELEASE.jar 10 | CLOJURE=$CLOJURE:$REPO/org/springframework/spring-asm/3.0.4.RELEASE/spring-asm-3.0.4.RELEASE.jar 11 | CLOJURE=$CLOJURE:$REPO/org/springframework/spring-expression/3.0.4.RELEASE/spring-expression-3.0.4.RELEASE.jar 12 | CLOJURE=$CLOJURE:$REPO/org/springframework/spring-asm/3.0.4.RELEASE/spring-asm-3.0.4.RELEASE.jar 13 | CLOJURE=$CLOJURE:$REPO/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar 14 | CLOJURE=$CLOJURE:$REPO/org/slf4j/slf4j-api/1.6.3/slf4j-api-1.6.3.jar 15 | CLOJURE=$CLOJURE:$REPO/me/raynes/fs/1.4.5/fs-1.4.5.jar 16 | CLOJURE=$CLOJURE:./src/test/clojure 17 | CLOJURE=$CLOJURE:$REPO/net/matlux/jvm-breakglass/0.0.7/jvm-breakglass-0.0.7.jar 18 | CLOJURE=$CLOJURE:./target/server-test-1.0-SNAPSHOT.jar 19 | CLOJURE=$CLOJURE:${PWD} 20 | 21 | OPTIONS=-Dcom.sun.management.jmxremote.port=9595 22 | OPTIONS=$OPTIONS\ -Dcom.sun.management.jmxremote.ssl=false 23 | OPTIONS=$OPTIONS\ -Dcom.sun.management.jmxremote.authenticate=false 24 | OPTIONS=$OPTIONS\ -Djava.rmi.server.hostname=localhost 25 | #OPTIONS=$OPTIONS\ -Djava.rmi.server.hostname=192.168.0.20 26 | 27 | java -cp "$CLOJURE" $OPTIONS net.matlux.testserver.SpringServerExample "$@" 28 | -------------------------------------------------------------------------------- /examples/server/stopServer.sh: -------------------------------------------------------------------------------- 1 | ps | grep java | grep -v grep | awk '{print $1}' | xargs kill -9 2 | -------------------------------------------------------------------------------- /presentation/skillsmatter_nreplboot_pres.odp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matlux/jvm-breakglass/e6d107ddd8a686bc27ed46dd803c53b16d98f389/presentation/skillsmatter_nreplboot_pres.odp --------------------------------------------------------------------------------