{"id":5924,"date":"2013-10-15T02:40:02","date_gmt":"2013-10-15T09:40:02","guid":{"rendered":"http:\/\/localhost\/exoblog\/?p=5924"},"modified":"2023-06-05T16:39:51","modified_gmt":"2023-06-05T14:39:51","slug":"introduction-to-crash-the-cache-visualization-use-case","status":"publish","type":"post","link":"https:\/\/www.exoplatform.com\/blog\/introduction-to-crash-the-cache-visualization-use-case\/","title":{"rendered":"Introduction to CRaSH: The Cache Visualization Use Case"},"content":{"rendered":"<p><i>This post is an adaptation of an article originally <a href=\"http:\/\/damienrieu.developpez.com\/article\/crash_ehcache_spring\/\" target=\"_blank\" rel=\"noopener\">written and published in French by Rieu Damien<\/a>.<\/i><\/p>\n<h2>CRaSH: A shell to extend the Java Platform<\/h2>\n<p>CRaSH is an open source project created by Julien Viet (co-president of the<a href=\"http:\/\/marsjug.org\/\" target=\"_blank\" rel=\"noopener\"> Marseille JUG<\/a>). I discovered CRaSH at a session of the Marseille JUG and I now contribute to its development.<\/p>\n<p>This article introduces CRaSH through a case study and shows how you can easily work directly in the heart of the JVM. Have a good CRaSH!<\/p>\n<p><!--more--><\/p>\n<h2>I. Introduction<\/h2>\n<p>CRaSH can connect to a JVM in shell mode and execute commands directly on the JVM. Thus, we\u2019ll be able to access a number of predefined commands (such as thread, jdbc and java). If you want a quick overview of the available commands and their uses, they are available for testing on the <strong>CRaSH demo site<\/strong>.<\/p>\n<p>One of the great strengths of CRaSH is that we can also define our own shell commands by programming them. It is then possible to carry out commands specific to our needs!<\/p>\n<p>In this tutorial, we will present CRaSH through a use case. For this, we will create a CRaSH command to display a cache, then we will integrate this control into our application.<\/p>\n<p>We\u2019ll then see how to use this command with CRaSH.<\/p>\n<p>The demo application was made with Spring. In this article, we\u2019ll show how easy it is to integrate CRaSH into a Spring application.<\/p>\n<h2>II. Prerequisites and Installation<\/h2>\n<h2>II-A. Prerequisites<\/h2>\n<ul>\n<li>JBoss 7.1.1<\/li>\n<li>Maven 3<\/li>\n<li>The app code can be found on GitHub: <a href=\"https:\/\/github.com\/crashub\/spring-ehcache-demo\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/crashub\/spring-ehcache-demo<\/a>.<\/li>\n<\/ul>\n<h2>II-B. Installation<\/h2>\n<p>To install CRaSH, download the CRaSH archive (<a href=\"http:\/\/www.crashub.org\/\" target=\"_blank\" rel=\"noopener\">www.crashub.org<\/a>) and decompress it. Installation is not required if you use the ssh or telnet mode.<\/p>\n<h2>II-C. Demo App Installation<\/h2>\n<ul>\n<li>Download the source code of the app from GitHub: <a href=\"https:\/\/github.com\/crashub\/spring-ehcache-demo\" target=\"_blank\" rel=\"noopener\"><b>https:\/\/github.com\/crashub\/spring-ehcache-demo<\/b><\/a>.<\/li>\n<li>Building the war file:<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true \">cd sandbox \nmvn clean package<\/pre>\n<ul>\n<li>Deployment in JBoss<\/li>\n<\/ul>\n<p>Once the war file is built, you just copy it to the JBoss deployment directory (<span class=\"navCode\">${JBOSS_DIR}\/standalone\/deployments<\/span>).<\/p>\n<p>Warning: The demo app has been tested only on jboss-as-7.1.1.Final.<\/p>\n<h2>III. CRaSH Overview<\/h2>\n<p>Here is the official definition of <b>CRaSH<\/b>:<\/p>\n<p><i>The Common Reusable SHell (CRaSH) deploys in a Java runtime and interacts with the JVM. Commands are written in Groovy and can be developed at runtime making extending the shell very easy with a fast development cycle.<\/i><\/p>\n<p>In summary, CRaSH is deployed in a Java runtime and allows you to interact with the JVM. With CRaSH, we can access the JVM using a shell. We can execute commands to see threads and classes, connect to available data sources and execute queries as if we were in the same place as the application!<\/p>\n<p>Here is a list of available commands:<\/p>\n<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/01-crash_help.jpeg\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-5936\" src=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/01-crash_help.jpeg\" alt=\"01-crash_help\" width=\"563\" height=\"466\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/01-crash_help.jpeg 563w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/01-crash_help-300x248.jpeg 300w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/01-crash_help-396x328.jpeg 396w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/01-crash_help-285x236.jpeg 285w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/01-crash_help-158x131.jpeg 158w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/01-crash_help-100x83.jpeg 100w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/01-crash_help-36x30.jpeg 36w\" sizes=\"(max-width: 563px) 100vw, 563px\" \/><\/a><\/p>\n<p>These are the basic commands. However, a major strength of CRaSH is that you can make your own shell commands in Groovy (it doesn\u2019t matter if you don\u2019t know Groovy because Groovy recognizes Java syntax).<\/p>\n<p>In our demo example, we will create a Groovy script that will read the information in the cache.<\/p>\n<h2>IV. Demo Application<\/h2>\n<h2>IV-A. Objective<\/h2>\n<p>The objective is to control the demo application cache by connecting to the application JVM with CRaSH and run a display cache script.<\/p>\n<p>We will follow these steps:<\/p>\n<ul>\n<li>Create a script to display the cache: <span class=\"navCode\">spring_cache.groovy<\/span>.<\/li>\n<li>Integrate CRaSH into our demo application (adding Maven dependencies, <span class=\"navCode\">spring_cache.groovy<\/span> and configuration files).<\/li>\n<li>Package and deploy our demo app on JBoss.<\/li>\n<li>Use CRaSH.<\/li>\n<\/ul>\n<h2>IV-B. Demo Application Overview<\/h2>\n<p>The demo application is very simple. You can use it to list, add and delete users. To access the demo application, simply go to <span class=\"navCode\">http:\/\/localhost:8080\/demo\/<\/span>:<\/p>\n<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/02-crash_demo_home.jpeg\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-medium wp-image-5935\" src=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/02-crash_demo_home.jpeg\" alt=\"02-crash_demo_home\" width=\"300\" height=\"217\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/02-crash_demo_home.jpeg 994w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/02-crash_demo_home-300x218.jpeg 300w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/02-crash_demo_home-768x558.jpeg 768w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/02-crash_demo_home-651x473.jpeg 651w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/02-crash_demo_home-452x328.jpeg 452w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/02-crash_demo_home-325x236.jpeg 325w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/02-crash_demo_home-180x131.jpeg 180w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/02-crash_demo_home-100x73.jpeg 100w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/02-crash_demo_home-41x30.jpeg 41w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<h2>IV-C. Creating a Display Cache Script: spring_cache.groovy<\/h2>\n<p>To display the data in our cache, we need a script. This script will be placed in the <span class=\"navCode\">WEB-INF\/crash\/commands\/<\/span> directory of our demo application.<\/p>\n<p>Note: In this version (<span class=\"navCode\">crsh.shell.embed.spring<\/span> 1.1), it is mandatory to add scripts in the <span class=\"navCode\">WEB-INF\/crash\/commands\/<\/span> directory.<\/p>\n<h2>IV-C-1. How does this script works?<\/h2>\n<p>This script retrieves the <span class=\"navCode\">customerComponent<\/span> bean that exists in the environment. It is then possible to retrieve the list of customers by calling the <span class=\"navCode\">getCache()<\/span> method of the bean: <span class=\"navCode\">List&lt;Customer&gt; lst = bean.getCache();<\/span><\/p>\n<p>Then the script loops through the list of customers and displays their details.<\/p>\n<h2>IV-C-2. The Display Cache Script<\/h2>\n<p>This script will define a CRaSH command, which will be available in shell mode:<\/p>\n<ul>\n<li>The command name is the name of the Groovy class. In our case, this is <span class=\"navCode\">spring_cache<\/span>.<\/li>\n<li>This command may have several sub-commands. In our case, we defined the subcommand <span class=\"navCode\">showCache<\/span>.<\/li>\n<\/ul>\n<p>So to call <span class=\"navCode\">showCache<\/span>, simply type in the CRaSH shell:<\/p>\n<pre class=\"lang:default decode:true \">%spring_cache showCache<\/pre>\n<p>Here is the code of the <span class=\"navCode\">spring_cache<\/span> command:<\/p>\n<pre class=\"lang:default decode:true \">package crash.commands.base\nimport org.crsh.command.CRaSHCommand\nimport org.crsh.cmdline.annotations.Usage\nimport org.crsh.cmdline.annotations.Command\nimport org.crsh.cmdline.annotations.Argument\n\nimport org.crsh.cmdline.annotations.Required\nimport org.crsh.shell.ui.UIBuilder\n\nimport fr.dr.sandbox.controller.Customer;\nimport fr.dr.sandbox.controller.CustomerComponent;\nimport java.lang.reflect.Method;\nimport java.util.List;\n\n\/**\n* Spring commands to list Customer in cache for the demo application.\n* @author drieu\n*\n*\/\n@Usage(\"Spring cache commands\")\n@Command\nclass spring_cache extends CRaSHCommand {\n\n @Usage(\"Show values that are loaded in cache\")\n @Command\n public void showCache() {\n   def bean = context.attributes.beans[\"customerComponent\"];\n   if (null != bean) {\n     out.println(\"Cache contents :\");\n     List&lt;Customer&gt; lst = bean.getCache();\n     if (null != lst) {\n     for(Customer c : lst) {\n         out.println(\"Name:\" + c.getName());\n         out.println(\"Id:\" + c.getId());\n         c.show();\n    }\n  }\n }\n }\n}\n<\/pre>\n<p>See Appendix V.E for more details on how to create a command. This command is written in Groovy. However, the syntax we are using here is the same as Java.<\/p>\n<h2>IV-C-3. Integrating CRaSH into our Demo App<\/h2>\n<p>Integrating CRaSH into an application is very simple:<\/p>\n<ul>\n<li>Add the CRaSH Maven dependency.<\/li>\n<li>Add a configuration bean.<\/li>\n<li>Add the <span class=\"navCode\">spring_cache.groovy<\/span> script already created.<\/li>\n<li>Package everything into a war file.<\/li>\n<\/ul>\n<p>For this script to be available, it should be placed in <span class=\"navCode\">WEB-INF\/crash\/commands\/<\/span>. Of course you can create as many scripts as you want and put them in this directory.<\/p>\n<p>In some cases, it is possible to edit, delete or add commands dynamically. The command is then automatically reloaded!<\/p>\n<h2>IV-C-4. Adding Maven Dependencies<\/h2>\n<p>In your <span class=\"navCode\">pom.xml<\/span>:<\/p>\n<pre class=\"lang:default decode:true \">&lt;dependency&gt;\n    &lt;groupId&gt;org.crsh&lt;\/groupId&gt;\n       &lt;artifactId&gt;crsh.shell.embed.spring&lt;\/artifactId&gt;\n       &lt;version&gt;1.1.0&lt;\/version&gt;\n&lt;\/dependency&gt;\n&lt;dependency&gt;\n   &lt;groupId&gt;org.crsh&lt;\/groupId&gt;\n   &lt;artifactId&gt;crsh.shell.core&lt;\/artifactId&gt;\n   &lt;version&gt;1.1.0&lt;\/version&gt;\n&lt;\/dependency&gt;\n&lt;dependency&gt;\n   &lt;groupId&gt;org.crsh&lt;\/groupId&gt;\n   &lt;artifactId&gt;crsh.shell.packaging&lt;\/artifactId&gt;\n   &lt;version&gt;1.1.0&lt;\/version&gt;\n   &lt;type&gt;war&lt;\/type&gt;\n   &lt;classifier&gt;spring&lt;\/classifier&gt;\n&lt;\/dependency&gt;<\/pre>\n<p>Warning: CRaSH uses the Spring 3.1.1.RELEASE version but it should work with all versions of Spring.<\/p>\n<h2>IV-C-5. Configuration of the CRaSH Access Modes<\/h2>\n<p>This step is optional because you can connect directly to the JVM (see the appendix on connection modes).<\/p>\n<p>On the other hand, if you want to use ssh or telnet modes, you only need to modify a bean (see the <span class=\"navCode\">spring.xml<\/span> file of the demo application).<\/p>\n<p>In the example below, we configure Telnet access through port 5000 and we also add an ssh connection on port 2000 with the admin user.<\/p>\n<p>Example:<\/p>\n<pre class=\"lang:default decode:true \">&lt;bean class=\"org.crsh.spring.SpringWebBootstrap\"&gt;\n\t&lt;property name=\"config\"&gt;\n\t\t&lt;props&gt;\n\t\t\t&lt;prop key=\"crash.telnet.port\"&gt;5000&lt;\/prop&gt;\n\t\t\t&lt;!-- VFS configuration --&gt;\n\t\t\t&lt;prop key=\"crash.vfs.refresh_period\"&gt;1&lt;\/prop&gt;\n\t\t\t&lt;!-- SSH configuration --&gt;\n\t\t\t&lt;prop key=\"crash.ssh.port\"&gt;2000&lt;\/prop&gt;\n\t\t\t&lt;!-- Authentication configuration --&gt;\n\t\t\t&lt;prop key=\"crash.auth\"&gt;simple&lt;\/prop&gt;\n\t\t\t&lt;prop key=\"crash.auth.simple.username\"&gt;admin&lt;\/prop&gt;\n\t\t\t&lt;prop key=\"crash.auth.simple.password\"&gt;admin&lt;\/prop&gt;\n\t\t&lt;\/props&gt;\n\t&lt;\/property&gt;\n&lt;\/bean&gt;\n&lt;bean class=\"org.crsh.telnet.TelnetPlugin\"\/&gt;<\/pre>\n<p>We can connect to our application as follows:<\/p>\n<pre class=\"lang:default decode:true \">telnet 5000 localhost\nssh -p 2000 -l admin localhost (mdp admin)<\/pre>\n<h2>IV-C-6. Packaging and Deployment<\/h2>\n<p>You build the war file by:<\/p>\n<pre class=\"lang:default decode:true \">mvn clean package<\/pre>\n<p>We then deploy this war file in JBoss. The application is then available at <span class=\"navCode\">http:\/\/localhost:8080\/demo\/<\/span>. In the following section, we will see how to use CRaSH.<\/p>\n<h2>IV-D. Using CRaSH<\/h2>\n<p>Using CRaSH is very simple. There are several ways to connect to a JVM:<\/p>\n<ul>\n<li>ssh mode<\/li>\n<li>telnet mode<\/li>\n<li>Attach mode<\/li>\n<\/ul>\n<p>In our example, we will use the ssh mode. Since CRaSH is embedded in the demo application with the ssh configuration (admin user and port 2000), you only need to have an ssh client to connect:<\/p>\n<pre class=\"lang:default decode:true \">ssh -p 2000 -l admin localhost\n<\/pre>\n<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/03-crash_welcome.jpeg\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-medium wp-image-5934\" src=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/03-crash_welcome.jpeg\" alt=\"03-crash_welcome\" width=\"300\" height=\"133\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/03-crash_welcome.jpeg 559w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/03-crash_welcome-300x133.jpeg 300w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/03-crash_welcome-500x222.jpeg 500w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/03-crash_welcome-360x160.jpeg 360w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/03-crash_welcome-200x89.jpeg 200w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/03-crash_welcome-100x44.jpeg 100w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/03-crash_welcome-68x30.jpeg 68w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Once connected, you can type <span class=\"navCode\">help<\/span> for a list of the available commands:<\/p>\n<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/04-crash_welcome_help.jpeg\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-medium wp-image-5933\" src=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/04-crash_welcome_help.jpeg\" alt=\"04-crash_welcome_help\" width=\"300\" height=\"265\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/04-crash_welcome_help.jpeg 540w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/04-crash_welcome_help-300x266.jpeg 300w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/04-crash_welcome_help-534x473.jpeg 534w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/04-crash_welcome_help-371x328.jpeg 371w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/04-crash_welcome_help-267x236.jpeg 267w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/04-crash_welcome_help-148x131.jpeg 148w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/04-crash_welcome_help-34x30.jpeg 34w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Notice that our <span class=\"navCode\">spring_cache<\/span> command is listed. To get the help for this command, enter: <span class=\"navCode\">spring_cache<\/span>.<\/p>\n<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/05-spring_cache_help.jpeg\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-medium wp-image-5932\" src=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/05-spring_cache_help.jpeg\" alt=\"05-spring_cache_help\" width=\"300\" height=\"124\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/05-spring_cache_help.jpeg 303w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/05-spring_cache_help-300x125.jpeg 300w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/05-spring_cache_help-200x83.jpeg 200w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/05-spring_cache_help-100x42.jpeg 100w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/05-spring_cache_help-70x30.jpeg 70w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>To use this command, just type: <span class=\"navCode\">spring_cache showcache<\/span>. This command displays a list of the customers in our cache.<\/p>\n<p>At startup, we loaded a user into our cache (see the appendix):<\/p>\n<pre class=\"lang:default decode:true \">% spring_cache showcache \nCache contents : \nName:Smith \nId:1<\/pre>\n<p>We can add another user into our cache, just click on \u201cAdd customer\u201d on <span class=\"navCode\">http:\/\/localhost:8080\/demo\/<\/span>.<\/p>\n<p>If we return to the home page after adding the customer, we will see two lines in our table:<\/p>\n<p><a href=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/06-crash_show_two_customer.jpeg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-5931\" src=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/06-crash_show_two_customer.jpeg\" alt=\"06-crash_show_two_customer\" width=\"650\" srcset=\"https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/06-crash_show_two_customer.jpeg 1028w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/06-crash_show_two_customer-300x164.jpeg 300w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/06-crash_show_two_customer-1024x560.jpeg 1024w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/06-crash_show_two_customer-768x420.jpeg 768w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/06-crash_show_two_customer-720x394.jpeg 720w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/06-crash_show_two_customer-500x273.jpeg 500w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/06-crash_show_two_customer-360x197.jpeg 360w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/06-crash_show_two_customer-200x109.jpeg 200w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/06-crash_show_two_customer-100x55.jpeg 100w, https:\/\/www.exoplatform.com\/blog\/wp-content\/uploads\/2013\/10\/06-crash_show_two_customer-55x30.jpeg 55w\" sizes=\"(max-width: 1028px) 100vw, 1028px\" \/><\/a><\/p>\n<p>Then, if we return to our shell, we see that the cache has been updated:<\/p>\n<pre class=\"lang:default decode:true \">% spring_cache showcache \nCache contents : \nName:Smith \nId:1\nName:john \nId:2<\/pre>\n<h2>V. Appendices<\/h2>\n<h2>V-A. Functioning of the Demo Application Cache<\/h2>\n<p>This section describes how we implemented cache management in the demo app for the following cases:<\/p>\n<ul>\n<li>at startup<\/li>\n<li>in the application<\/li>\n<\/ul>\n<p>We use <b>ehcache<\/b> 1.6.1 with Spring 3.1.1.RELEASE in our demo application.<\/p>\n<p>For this, we define a cacheManager with Spring in the <span class=\"navCode\">sandbox.xml<\/span> file:<\/p>\n<pre class=\"lang:default decode:true \">&lt;ehcache:annotation-driven cache-manager=\"cacheManager\" \/&gt;<\/pre>\n<p>We then use the cacheManager in our application to perform read, write and erase operations. We access the cache in two ways:<\/p>\n<ul>\n<li>at startup<\/li>\n<li>through the web interface<\/li>\n<\/ul>\n<h2>V-B. Cache Loading at Startup<\/h2>\n<p>We will put a customer into the cache at startup. We defined a listener in our <span class=\"navCode\">web.xml<\/span> file:<\/p>\n<pre class=\"lang:default decode:true \">&lt;listener-class&gt; \nfr.dr.sandbox.listener.CacheListener \n&lt;\/listener-class&gt;<\/pre>\n<p>This listener contains a context-initialized method into which we put our code for loading a customer into the cache.<\/p>\n<pre class=\"lang:default decode:true \">CacheManager cacheManager = (CacheManager) WebApplicationContextUtils.getWebApplicationContext(servletContext).getBean(\"cacheManager\"); \nCache cache = cacheManager.getCache(\"customer\"); \nCustomer c = new Customer(); \nc.setId(\"1\"); \nc.setName(\"Smith\"); \nc.setAddress(\"Smith Address\"); \ncache.put(new Element(c.getId(),c));<\/pre>\n<p>After application startup, there is a log of this loading:<\/p>\n<pre class=\"lang:default decode:true \">14:53:32,044 INFO  [fr.dr.sandbox.listener.CacheListener] (MSC service thread 1-2) ========&gt; contextInitialized() : BEGIN. \n14:53:32,047 INFO  [fr.dr.sandbox.listener.CacheListener] (MSC service thread 1-2) ========&gt; contextInitialized() : Customer Smith was added in cache. \n14:53:32,047 INFO  [fr.dr.sandbox.listener.CacheListener] (MSC service thread 1-2) ========&gt; contextInitialized() : END<\/pre>\n<h2>V-C. Accessing the Cache via the Web Interface<\/h2>\n<p>It is possible to perform cache operations via the web interface. We define operations in the Controller that will call the caching methods that are in CustomerComponent.<\/p>\n<p>Example:<\/p>\n<p>Accessing <span class=\"navCode\">http:\/\/localhost:8080\/demo\/clearCache<\/span> will call the following Controller method:<\/p>\n<pre class=\"lang:default decode:true \">\/** \n* Clear all data in cache. \n* @return String text message OK or KO. \n*\/ \n@RequestMapping(value = \"\/clearCache\", method = { RequestMethod.GET }) \n@ResponseStatus(HttpStatus.OK) \npublic @ResponseBody \nString clearCache() { \n\tcustomerComponent.clearCache(); \n\treturn \"Cache successfully Cleaned\"; \n} \n<\/pre>\n<h2>V-D. Connection Modes<\/h2>\n<p>CRaSH provides several options for connecting to JVMs. Here we\u2019ll present the different methods.<\/p>\n<h2>V-D-1. Standalone Mode<\/h2>\n<p>This mode allows you to start CRaSH directly from the shell:<\/p>\n<pre class=\"lang:default decode:true \">%cd $CRASH_HOME\/bin\n%crash.sh<\/pre>\n<p>This starts CRaSH with its own JVM.<\/p>\n<h2>V-D-2. Attach Mode<\/h2>\n<p>This mode is used to connect CRaSH to a local JVM. For a list of available local JVMs, use the jps command in the JDK:<\/p>\n<pre class=\"lang:default decode:true \">%$JDK_HOME\/bin\/jps\n3165 RemoteMavenServer\n20650 Test\n20651 Jps<\/pre>\n<p>To connect, simply pass the JVM PID to CRaSH:<\/p>\n<pre class=\"lang:default decode:true \">%cd $CRASH_HOME\/bin\n%crash.sh 20650<\/pre>\n<h2>V-D-3. Embedded Mode<\/h2>\n<p>CRaSH can be embedded in a web application deployed on an application server. This is the case for our demo application.<\/p>\n<h2>V-D-4. Other Modes<\/h2>\n<p>CRaSH also comes in the form of a war file, which is deployed on an application server. Thus, we can access the application server\u2019s JVM and can for example connect to available data sources and execute queries.<\/p>\n<p>There are several methods for connecting to CRaSH deployed \u200b\u200bon an application server:<\/p>\n<ul>\n<li>ssh mode<\/li>\n<li>telnet mode<\/li>\n<li>attach mode<\/li>\n<\/ul>\n<h2>V-E. Creating a CRaSH Command<\/h2>\n<p>There are two ways to create a command:<\/p>\n<ul>\n<li>1. As a script<\/li>\n<\/ul>\n<p>In this case, put the code into the Groovy script. Here is an example of a clock command:<\/p>\n<pre class=\"lang:default decode:true \">package crash.commands.base\nfor (int i = 0;i &lt; 10;i++) {\n\tout.cls();\n\tout &lt;&lt; \"Time is\" + i + \"\\n\";\n\tout.flush();\n\tThread.sleep(1000);\n}<\/pre>\n<ul>\n<li>2. As a class<\/li>\n<\/ul>\n<p>This method greatly simplifies the creation of commands. In this section, we present only the basic annotations needed to create a command. There are many possibilities for CRaSH commands. You can, for example, add completion and create result tables.<\/p>\n<p>For more information, check the document on <a href=\"http:\/\/www.crashub.org\/\" target=\"_blank\" rel=\"noopener\">www.crashub.org<\/a>.<\/p>\n<p>Here is a command structure:<\/p>\n<pre class=\"lang:default decode:true \">@Usage(\"JDBC connection\")\nclass jdbc extends CRaSHCommand {\n  \n  @Usage(\"connect to database with a JDBC connection string\")\n  @Command\n  public String connect(\n ...\n  }<\/pre>\n<p><span class=\"navCode\">@Command<\/span>: defines that a method or a class is a command.<\/p>\n<p><span class=\"navCode\">@Usage<\/span>: defines the help that will be displayed. If it is placed on top of the class that extends a command then this help will be displayed with the help command. In our case, when the help command is passed, we will have the following output with the <span class=\"navCode\">@Usage(&#8220;JDBC connection&#8221;)<\/span> annotation.<\/p>\n<pre class=\"lang:default decode:true \">%help\nTry on of the following commands with -h or --help switch:\n\nNAME    DESCRIPTION\nenv     dipslay the term env\nhelp    provides basic help\njava    various java language commands\njdbc    JDBC connection<\/pre>\n<p>We can also place this annotation above a method identified as a command. For example, for the JDBC connect method, we have: <span class=\"navCode\">@Usage(&#8220;connect to database with a JDBC connection string&#8221;)<\/span>. So if we input:<\/p>\n<pre class=\"lang:default decode:true \">%jdbc help<\/pre>\n<p>We\u2019ll get the following description:<\/p>\n<pre class=\"lang:default decode:true \">The most commonly used jdbc commands are:\n   props            show the database properties\n   close            close the current connection\n   table            describe the tables\n   open             open a connection from JNDI bound datasource\n   connect          connect to database with a JDBC connection string\n   execute          execute SQL statement\n   info             describe the database\n   tables           describe the tables<\/pre>\n<p>There are also annotations to define the arguments (example: @Argument) and options, for example, <span class=\"navCode\">@Option(names=[&#8220;p&#8221;,&#8221;password&#8221;])<\/span>.<\/p>\n<h2>VI. Conclusion and Acknowledgments<\/h2>\n<p>I hope you enjoyed this article and that you now want to use and learn more about CRaSH.<\/p>\n<p>Thanks to<a href=\"http:\/\/www.developpez.net\/forums\/u69211\/keulkeul\/\" target=\"_blank\" rel=\"noopener\"> Mickael BARON<\/a> for his patience and the quality of his observations and <a href=\"http:\/\/www.developpez.net\/forums\/u124512\/claudeleloup\" target=\"_blank\" rel=\"noopener\">Claude Leloup<\/a> for his careful and diligent review. I also thank Julien Viet and <a href=\"http:\/\/www.developpez.net\/forums\/u68951\/romaintaz\/\" target=\"_blank\" rel=\"noopener\">Romain Linsolas<\/a> for their reviews.<\/p>\n<p><i>Thanks again to Damien Rieu for his great article. For more information and useful resources on how to use CRaSH with eXo Platform, <a href=\"https:\/\/community.exoplatform.com\/portal\/dw\/\" target=\"_blank\" rel=\"noopener\">head to the community website<\/a>! You can also find the original article in French <a href=\"http:\/\/damienrieu.developpez.com\/article\/crash_ehcache_spring\/\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/i><\/p>\n","protected":false},"excerpt":{"rendered":"This post is an adaptation of an article originally written and published in French by Rieu Damien. CRaSH: A shell to extend the Java Platform CRaSH is an open source project created by Julien Viet (co-president of the Marseille JUG). I discovered CRaSH at a session of the Marseille JUG and I now contribute to [&hellip;]","protected":false},"author":7,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[699],"tags":[],"lang":"en","translations":{"en":5924},"pll_sync_post":[],"_links":{"self":[{"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/posts\/5924"}],"collection":[{"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/comments?post=5924"}],"version-history":[{"count":0,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/posts\/5924\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/media?parent=5924"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/categories?post=5924"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.exoplatform.com\/blog\/wp-json\/wp\/v2\/tags?post=5924"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}