{"id":920,"date":"2017-09-22T18:00:25","date_gmt":"2017-09-22T17:00:25","guid":{"rendered":"http:\/\/hirt.se\/blog\/?p=920"},"modified":"2017-09-21T20:26:50","modified_gmt":"2017-09-21T19:26:50","slug":"jmc-6-automated-analysis-headless","status":"publish","type":"post","link":"https:\/\/hirt.se\/blog\/?p=920","title":{"rendered":"JMC 6 Automated Analysis Headless"},"content":{"rendered":"<p>This post will be a little bit wider than the title implies; it will be about using the JMC core JFR APIs in general. That said, one of the things we will be using it for, towards the end, will be to run the JMC 6 automated analysis headless.<\/p>\n<p>This article will also cheat by talking about JMC 6.1, so that anyone reading this article will have relevant information for JMC 6.1 as well. <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-winkingsmile\" alt=\"Winking smile\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/wlEmoticon-winkingsmile-1.png\">&nbsp;<\/p>\n<h2>The JAR-files Needed<\/h2>\n<p>To run these examples you will need to have the following Jar-files from the JDK_HOME\/lib\/missioncontrol\/plugins folder on your classpath:<\/p>\n<table width=\"90%\" border=\"1\" cellspacing=\"0\" cellpadding=\"2\">\n<tbody>\n<tr>\n<th valign=\"top\">\n<p align=\"left\">Prefix<\/p>\n<\/th>\n<th valign=\"top\">\n<p align=\"center\">Version needed<\/p>\n<\/th>\n<th valign=\"top\">\n<p align=\"left\">Comment<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td valign=\"top\">com.oracle.jmc.common<\/td>\n<td valign=\"top\">\n<p align=\"center\">&gt;= 6.0.0<\/p>\n<\/td>\n<td valign=\"top\">Classes common to JMC, such as stacktrace definitions, the content type system (quantities\/ units of measurement) etc. <\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">com.oracle.jmc.flightrecorder<\/td>\n<td valign=\"top\">\n<p align=\"center\">&gt;= 6.0.0<\/p>\n<\/td>\n<td valign=\"top\">The Java Flight Recorder parser, classes for extracting information from a recording.<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">com.oracle.jmc.flightrecorder.rules<\/td>\n<td valign=\"top\">\n<p align=\"center\">&gt;= 6.0.0<\/p>\n<\/td>\n<td valign=\"top\">The core definitions and classes for automated analysis of recordings.<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">com.oracle.jmc.flightrecorder.rules.jdk<\/td>\n<td valign=\"top\">\n<p align=\"center\">&gt;= 6.0.0<\/p>\n<\/td>\n<td valign=\"top\">Contains the rules for the JDK (such as rules for synchronization trouble, long lasting VM operations and much more).<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">com.oracle.jmc.flightrecorder.ext.wls.parser<\/td>\n<td valign=\"top\">\n<p align=\"center\">&gt;= 6.0.0<\/p>\n<\/td>\n<td valign=\"top\">(<font color=\"#ff0000\">Optional<\/font>, only relevant for users wanting WebLogic Server extensions)<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">com.oracle.jmc.flightrecorder.ext.wls.rules<\/td>\n<td valign=\"top\">\n<p align=\"center\">&gt;= 6.0.0<\/p>\n<\/td>\n<td valign=\"top\">(<font color=\"#ff0000\">Optional<\/font>, only relevant for users wanting WebLogic Server extensions)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Loading a Recording<\/h2>\n<p>\nLoading a recording is done through a call to the JfrLoaderToolkit#loadEvents(). It takes a file argument, and returns an IItemCollection. The IItemCollection can be thought of as a collection of events.<\/p>\n<p>The <font color=\"#ff0000\">IItemCollection<\/font> supports operations like filter(), and getAggregate(). Used correctly, you should rarely need to rely on external iteration.<\/p>\n<p>Here is an example which loads a recording, and calculates the standard deviation for the java monitor enter events in a recording:<\/p>\n<p><pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nimport java.io.File;\r\n\r\nimport com.oracle.jmc.common.IDisplayable;\r\nimport com.oracle.jmc.common.item.Aggregators;\r\nimport com.oracle.jmc.common.item.IItemCollection;\r\nimport com.oracle.jmc.common.item.ItemFilters;\r\nimport com.oracle.jmc.common.unit.IQuantity;\r\nimport com.oracle.jmc.flightrecorder.JfrAttributes;\r\nimport com.oracle.jmc.flightrecorder.JfrLoaderToolkit;\r\nimport com.oracle.jmc.flightrecorder.jdk.JdkTypeIDs;\r\n\r\n\/**\r\n * Finds out the standard deviation for the java monitor enter events.\r\n *\/\r\npublic class LoadRecording {\r\n\tpublic static void main(String&#x5B;] args) throws Exception {\r\n\t\tDemoToolkit.verifyFirstFileArgument(RunRulesOnFile.class, args);\r\n\t\t\r\n\t\tIItemCollection events = JfrLoaderToolkit.loadEvents(new File(args&#x5B;0]));\r\n\t\tIQuantity aggregate = events.apply(ItemFilters.type(JdkTypeIDs.MONITOR_ENTER))\r\n\t\t\t\t.getAggregate(Aggregators.stddev(JfrAttributes.DURATION));\r\n\t\t\r\n\t\tSystem.out.println(&quot;The standard deviation for the Java monitor enter events was &quot;\r\n\t\t\t\t+ aggregate.displayUsing(IDisplayable.AUTO));\r\n\t}\r\n}\r\n<\/pre>\n<\/p>\n<p>\nNote the stream-like syntax. The JMC libraries work well together with streams, but are compiled on JDK 7, and can run on a JDK 7 compliant runtime. Also note that some class names start with <font color=\"#ff0000\">Jfr<\/font> whilst others class names start with <font color=\"#ff0000\">Jdk<\/font>. The difference being that some concepts, like DURATION, are intrinsic to JFR, whilst other are defined in terms of the Java JDK classes or runtime, like MONITOR_ENTER.<\/p>\n<p>The JMC core libraries provide common statistical aggregators, and accessors for common attributes. Should you feel something is missing, it is easy to add to the built-in operations. <\/p>\n<p>Also note the IQuantity returned by the aggregator. The built-in system for handling quantities and units of measurement makes it easy to calculate with, and display, quantities in different units of measurement.<\/p>\n<h2>Performing an Automated Analysis Headless<\/h2>\n<p>It is also easy to run the JMC rules headless using these core libraries. Simply evaluate the rules against the <font color=\"#ff0000\">IItemCollection<\/font>. Here is a simple example iterating through the rules and evaluating them one by one:<\/p>\n<p><pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nimport java.io.File;\r\nimport java.util.concurrent.RunnableFuture;\r\n\r\nimport com.oracle.example.jmc6jfr.rules.util.DemoToolkit;\r\nimport com.oracle.jmc.common.item.IItemCollection;\r\nimport com.oracle.jmc.common.util.IPreferenceValueProvider;\r\nimport com.oracle.jmc.flightrecorder.JfrLoaderToolkit;\r\nimport com.oracle.jmc.flightrecorder.rules.IRule;\r\nimport com.oracle.jmc.flightrecorder.rules.Result;\r\nimport com.oracle.jmc.flightrecorder.rules.RuleRegistry;\r\n\r\npublic class RunRulesOnFileSimple {\r\n\tpublic static void main(String&#x5B;] args) throws Exception {\r\n\t\tFile recording = DemoToolkit.verifyRecordingArgument(RunRulesOnFileSimple.class, args);\r\n\t\tIItemCollection events = JfrLoaderToolkit.loadEvents(recording);\r\n\t\t\r\n\t\tfor (IRule rule : RuleRegistry.getRules()) {\r\n\t\t\tRunnableFuture&lt;Result&gt; future = rule.evaluate(events, IPreferenceValueProvider.DEFAULT_VALUES);\r\n\t\t\tfuture.run();\r\n\t\t\tResult result = future.get();\r\n\t\t\tif (result.getScore() &gt; 50) {\r\n\t\t\t\tSystem.out.println(String.format(&quot;&#x5B;Score: %3.0f] Rule ID: %s, Rule name: %s, Short description: %s&quot;,\r\n\t\t\t\t\t\tresult.getScore(), result.getRule().getId(), result.getRule().getName(),\r\n\t\t\t\t\t\tresult.getShortDescription()));\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n<\/pre>\n<\/p>\n<p>That said, if you are not constrained to have to run on JDK 7, you can always run the rules in parallel, for example by employing parallel streams:<\/p>\n<p><pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nimport java.io.File;\r\nimport java.util.List;\r\nimport java.util.concurrent.ExecutionException;\r\nimport java.util.concurrent.Executor;\r\nimport java.util.concurrent.Executors;\r\nimport java.util.concurrent.RunnableFuture;\r\nimport java.util.stream.Collectors;\r\nimport java.util.stream.Stream;\r\n\r\nimport com.oracle.jmc.common.item.IItemCollection;\r\nimport com.oracle.jmc.common.util.IPreferenceValueProvider;\r\nimport com.oracle.jmc.flightrecorder.JfrLoaderToolkit;\r\nimport com.oracle.jmc.flightrecorder.rules.IRule;\r\nimport com.oracle.jmc.flightrecorder.rules.Result;\r\nimport com.oracle.jmc.flightrecorder.rules.RuleRegistry;\r\n\r\n\/**\r\n * Runs the rules on the events in the specified file in parallel, then prints\r\n * them in order of descending score.\r\n *\/\r\npublic class RunRulesOnFile {\r\n\tprivate final static Executor EXECUTOR = Executors\r\n\t\t\t.newFixedThreadPool(Runtime.getRuntime().availableProcessors() - 1);\r\n\tprivate static int limit;\r\n\r\n\tpublic static void main(String&#x5B;] args) throws Exception {\r\n\t\tif (args.length == 0) {\r\n\t\t\tSystem.out.println(\r\n\t\t\t\t\t&quot;Usage: RunRulesOnFile &lt;recording file&gt; &#x5B;&lt;limit&gt;]\\n\\tThe recording file must be a flight recording from JDK 7 or above. The limit, if set, will only report rules triggered with a score higher or equal than the limit.&quot;);\r\n\t\t\tSystem.exit(2);\r\n\t\t}\r\n\t\tIItemCollection events = JfrLoaderToolkit.loadEvents(new File(args&#x5B;0]));\r\n\t\tif (args.length &gt; 1) {\r\n\t\t\tlimit = Integer.parseInt(args&#x5B;1]);\r\n\t\t}\r\n\t\tStream&lt;RunnableFuture&lt;Result&gt;&gt; resultFutures = RuleRegistry.getRules().stream()\r\n\t\t\t\t.map((IRule r) -&gt; evaluate(r, events));\r\n\t\tList&lt;Result&gt; results = resultFutures.parallel().map((RunnableFuture&lt;Result&gt; runnable) -&gt; get(runnable))\r\n\t\t\t\t.collect(Collectors.toList());\r\n\t\tresults.sort((Result r1, Result r2) -&gt; Double.compare(r2.getScore(), r1.getScore()));\r\n\t\tresults.stream().forEach(RunRulesOnFile::printResult);\r\n\t}\r\n\r\n\tpublic static RunnableFuture&lt;Result&gt; evaluate(IRule rule, IItemCollection events) {\r\n\t\tRunnableFuture&lt;Result&gt; evaluation = rule.evaluate(events, IPreferenceValueProvider.DEFAULT_VALUES);\r\n\t\tEXECUTOR.execute(evaluation);\r\n\t\treturn evaluation;\r\n\t}\r\n\r\n\tpublic static Result get(RunnableFuture&lt;Result&gt; resultFuture) {\r\n\t\ttry {\r\n\t\t\treturn resultFuture.get();\r\n\t\t} catch (InterruptedException | ExecutionException e) {\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n\t\treturn null;\r\n\t}\r\n\r\n\tprivate static void printResult(Result result) {\r\n\t\tif (result.getScore() &gt;= limit) {\r\n\t\t\tSystem.out.printf(&quot;(%.0f) &#x5B;%s]: %s\\nDetails:\\n%s\\n============&lt;End of Result&gt;============\\n&quot;,\r\n\t\t\t\t\tresult.getScore(), result.getRule().getId(), result.getShortDescription(),\r\n\t\t\t\t\tresult.getLongDescription() == null ? &quot;&lt;no description&gt;&quot; : result.getLongDescription());\r\n\t\t}\r\n\t}\r\n}\r\n<\/pre>\n<\/p>\n<p>If you do not need that kind of control, there is a class available for performing automated analysis included with the JMC core library. To run an automatic analysis, simply run the class:<\/p>\n<blockquote>\n<p>com.oracle.jmc.flightrecorder.rules.report.JfrRulesReport &lt;files&gt; \u2013format &lt;format&gt; \u2013min &lt;severity&gt;<\/p>\n<\/blockquote>\n<p>\u2026where files is one or more recordings, and &lt;format&gt; is  and &lt;min&gt; is minimum severity to report [ok | info | warning]. In <strong><em>JMC 6.1.0<\/em><\/strong> there is one additional class for generating the file, which produces an HTML in a format and style very similar to the looks of the JMC 6.0.0 Automated Analysis page:<\/p>\n<blockquote>\n<p>com.oracle.jmc.flightrecorder.rules.report.html.JfrHtmlRulesReport &lt;file&gt; [&lt;outputfile&gt;]<\/p>\n<\/blockquote>\n<p>&#8230;where &lt;file&gt; is the (single) recording to analyze, and where the optional &lt;outputfile&gt; is where the resulting HTML should be written. If no outputfile is specified, the result of the analysis will be written on stdout.<\/p>\n<h2>Adding Custom Rules<\/h2>\n<p>It&#8217;s easy to add you own heuristics. Do you find yourself with thousands of recordings, and would like to add a Bayesiean network to do some machine learning? The rules are all pure Java, so you can pretty much do whatever you want in a rule.<\/p>\n<p>The easiest way to get started writing your own custom rules is to get yourself an Eclipse Oxygen or later, and install JMC and the experimental PDE plug-in into your Eclipse. <\/p>\n<ol>\n<li>Install Eclipse Oxygen or later.<\/li>\n<li>Got to the <a href=\"http:\/\/oracle.com\/missioncontrol\">Mission Control homepage<\/a>, and find the Eclipse Update site.<\/li>\n<li>Follow the instructions to install the Mission Control plug-ins.<br \/><a href=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image-6.png\"><img loading=\"lazy\" decoding=\"async\" width=\"244\" height=\"178\" title=\"image\" style=\"margin: 0px\" alt=\"image\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image_thumb-6.png\" border=\"0\"><\/a><\/li>\n<li>Got to the <a href=\"http:\/\/oracle.com\/missioncontrol\">Mission Control homepage<\/a>, and find the Experimental Update site.<\/li>\n<li>Install the PDE plug-in.<br \/><a href=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image-7.png\"><img loading=\"lazy\" decoding=\"async\" width=\"244\" height=\"222\" title=\"image\" style=\"margin: 0px\" alt=\"image\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image_thumb-7.png\" border=\"0\"><\/a><\/li>\n<\/ol>\n<p>Here is a cheat sheet for the eclipse update sites for the JMC 6.0.0 release: <\/p>\n<blockquote>\n<p><a title=\"http:\/\/download.oracle.com\/technology\/products\/missioncontrol\/updatesites\/base\/6.0.0\/eclipse\/\" href=\"http:\/\/download.oracle.com\/technology\/products\/missioncontrol\/updatesites\/base\/6.0.0\/eclipse\/\">http:\/\/download.oracle.com\/technology\/products\/missioncontrol\/updatesites\/base\/6.0.0\/eclipse\/<\/a><\/p>\n<p><a title=\"http:\/\/download.oracle.com\/technology\/products\/missioncontrol\/updatesites\/supported\/6.0.0\/eclipse\/\" href=\"http:\/\/download.oracle.com\/technology\/products\/missioncontrol\/updatesites\/supported\/6.0.0\/eclipse\/\">http:\/\/download.oracle.com\/technology\/products\/missioncontrol\/updatesites\/supported\/6.0.0\/eclipse\/<\/a><\/p>\n<p><a title=\"http:\/\/download.oracle.com\/technology\/products\/missioncontrol\/updatesites\/experimental\/6.0.0\/eclipse\/\" href=\"http:\/\/download.oracle.com\/technology\/products\/missioncontrol\/updatesites\/experimental\/6.0.0\/eclipse\/\">http:\/\/download.oracle.com\/technology\/products\/missioncontrol\/updatesites\/experimental\/6.0.0\/eclipse\/<\/a><\/p>\n<\/blockquote>\n<p>(JMC 6.1.0 will be released according to the same URL pattern.)<\/p>\n<p>To start building your rule, press ctrl-n (or click the <font color=\"#ff0000\">File | New | Other\u2026<\/font> menu) to bring up the New wizard. <\/p>\n<p><a href=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image-8.png\"><img loading=\"lazy\" decoding=\"async\" width=\"515\" height=\"497\" title=\"image\" alt=\"image\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image_thumb-8.png\" border=\"0\"><\/a><\/p>\n<p>Select<font color=\"#ff0000\"> Plug-in Project<\/font> and hit <font color=\"#ff0000\">Next<\/font>. Name your rule project something exciting.<\/p>\n<p><a href=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/pic.png\"><img loading=\"lazy\" decoding=\"async\" width=\"523\" height=\"621\" title=\"pic\" alt=\"pic\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/pic_thumb.png\" border=\"0\"><\/a><\/p>\n<p>Unclick that this plug-in will make contributions to the UI and hit Next.<\/p>\n<p><a href=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/pic2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"515\" height=\"621\" title=\"pic2\" alt=\"pic2\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/pic2_thumb.png\" border=\"0\"><\/a><\/p>\n<p>Next select the <font color=\"#ff0000\">Simple JFR Rule Wizard<\/font> and click <font color=\"#ff0000\">Finish<\/font> (or <font color=\"#ff0000\">Next<\/font>, if you really wish to do some further customizations).<\/p>\n<p><a href=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/pic3.png\"><img loading=\"lazy\" decoding=\"async\" width=\"632\" height=\"544\" title=\"pic3\" alt=\"pic3\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/pic3_thumb.png\" border=\"0\"><\/a><\/p>\n<p>You will now have a new project in your workspace, containing an example rule. If you have compilation errors, you need to set JMC to be your target platform (see the next section). You can either just export your rule, put it on the class path with the other core libraries, or you can try out your rule by running JMC from within Eclipse with your new rule. <\/p>\n<h2><\/h2>\n<h3>Starting JMC from within Eclipse with Workspace Plug-ins<\/h3>\n<p>Running JMC from within Eclipse with any plug-ins you are currently developing is a simple matter of setting the plug-in development target platform to your JMC installation, and launching that platform with your workspace plug-ins.<\/p>\n<p>First set JMC to be your target platform.<\/p>\n<ol>\n<li>Go to <font color=\"#ff0000\">Preferences<\/font> in the main menu (<font color=\"#ff0000\">Window | Preferences<\/font> on Windows).<\/li>\n<li>Find <font color=\"#ff0000\">Target Platform<\/font> by typing Tar in the filter box:<br \/><a href=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image-9.png\"><img loading=\"lazy\" decoding=\"async\" width=\"233\" height=\"244\" title=\"image\" alt=\"image\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image_thumb-9.png\" border=\"0\"><\/a><\/li>\n<li>Click Add\u2026 and type JMC 6 as name.<br \/><a href=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image-10.png\"><img loading=\"lazy\" decoding=\"async\" width=\"244\" height=\"223\" title=\"image\" style=\"margin: 0px\" alt=\"image\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image_thumb-10.png\" border=\"0\"><\/a><\/li>\n<li>Press Add\u2026 and select <font color=\"#ff0000\">Installation<\/font>. Hit Next. <br \/><a href=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image-11.png\"><img loading=\"lazy\" decoding=\"async\" width=\"244\" height=\"180\" title=\"image\" style=\"margin: 0px\" alt=\"image\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image_thumb-11.png\" border=\"0\"><\/a><\/li>\n<li><font color=\"#ff0000\">Browse<\/font> to the JMC 6 installation directory (JDK_9_HOME\/lib\/missioncontrol), and hit <font color=\"#ff0000\">Ok<\/font>.<br \/><a href=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/SNAGHTML1538a63d.png\"><img loading=\"lazy\" decoding=\"async\" width=\"226\" height=\"244\" title=\"SNAGHTML1538a63d\" style=\"margin: 0px\" alt=\"SNAGHTML1538a63d\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/SNAGHTML1538a63d_thumb.png\" border=\"0\"><\/a><\/li>\n<li>Hit <font color=\"#ff0000\">Finish<\/font>, and <font color=\"#ff0000\">Finish<\/font>. You should now see your new platform.<br \/><a href=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image-12.png\"><img loading=\"lazy\" decoding=\"async\" width=\"236\" height=\"244\" title=\"image\" style=\"margin: 0px\" alt=\"image\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image_thumb-12.png\" border=\"0\"><\/a><\/li>\n<li>Select the new JMC 6 platform, and hit Apply and Close to activate it.<br \/><a href=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image-13.png\"><img loading=\"lazy\" decoding=\"async\" width=\"236\" height=\"244\" title=\"image\" style=\"margin: 0px\" alt=\"image\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image_thumb-13.png\" border=\"0\"><\/a><\/li>\n<\/ol>\n<p>Everything should now compile cleanly. Next step is to run JMC with your new rule.<\/p>\n<ol>\n<li>Context click on your project and select Run as Eclipse Application<br \/><a href=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/SNAGHTML153e5cb4.png\"><img loading=\"lazy\" decoding=\"async\" width=\"244\" height=\"209\" title=\"SNAGHTML153e5cb4\" style=\"margin: 0px\" alt=\"SNAGHTML153e5cb4\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/SNAGHTML153e5cb4_thumb.png\" border=\"0\"><\/a><\/li>\n<li>This should normally be it. If you for some reason run into trouble, go to<font color=\"#ff0000\"> Run Configurations<\/font>, and make sure that your launcher is using the <font color=\"#ff0000\">com.oracle.jmc.rcp.application.product<\/font>.<br \/><a href=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/SNAGHTML1540e14b.png\"><img loading=\"lazy\" decoding=\"async\" width=\"240\" height=\"149\" title=\"SNAGHTML1540e14b\" style=\"border: 0px currentcolor\" alt=\"SNAGHTML1540e14b\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/SNAGHTML1540e14b_thumb.png\" border=\"0\"><\/a><\/li>\n<\/ol>\n<p>You should now be able to see your rule in action. If you have not changed the rule code, try setting the environment variable in the launcher to various values between 0 and 100 and see what happens when you run the rule in JMC:<\/p>\n<p><a href=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image-14.png\"><img loading=\"lazy\" decoding=\"async\" width=\"541\" height=\"484\" title=\"image\" alt=\"image\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image_thumb-14.png\" border=\"0\"><\/a><\/p>\n<p><a href=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image-15.png\"><img loading=\"lazy\" decoding=\"async\" width=\"644\" height=\"393\" title=\"image\" alt=\"image\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image_thumb-15.png\" border=\"0\"><\/a><\/p>\n<p><\/p>\n<h3>Exporting a Plug-in<\/h3>\n<p>You can export your rule by context-clicking on the project and selecting Export. In the Export wizard, select Deployable plug-ins and Fragments.<\/p>\n<p><a href=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image-16.png\"><img loading=\"lazy\" decoding=\"async\" width=\"244\" height=\"214\" title=\"image\" style=\"margin: 0px\" alt=\"image\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2017\/09\/image_thumb-16.png\" border=\"0\"><\/a>&nbsp;<\/p>\n<p>Click <font color=\"#ff0000\">Next<\/font>, select a folder to export the plug-in to and <font color=\"#ff0000\">Finish<\/font>. The resulting jar can either be put on the class path to be included in the headless analysis, or put in the dropins folder of any Java Mission Control installation where you would want the rule to be available.<\/p>\n<p><\/p>\n<h1>Summary<\/h1>\n<p>This blog described how to:<\/p>\n<ul>\n<li>Get started using the JMC core libraries to read Java Flight Recordings (JDK 7, 8 and 9)<\/li>\n<li>Get started doing headless analysis of Java Flight Recordings (JDK 7, 8 and 9)<\/li>\n<li>Get started creating custom rules for analyzing Java Flight Recordings<\/li>\n<\/ul>\n<p>Hope it helps someone!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post will be a little bit wider than the title implies; it will be about using the JMC core JFR APIs in general. That said, one of the things we will be using it for, towards the end, will be to run the JMC 6 automated analysis headless. This article will also cheat by [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[17,16,13,15],"class_list":["post-920","post","type-post","status-publish","format-standard","hentry","category-java-mission-control-fair-dj","tag-java-flight-recorder","tag-java-mission-control","tag-jfr","tag-jmc"],"_links":{"self":[{"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=\/wp\/v2\/posts\/920","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=920"}],"version-history":[{"count":10,"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=\/wp\/v2\/posts\/920\/revisions"}],"predecessor-version":[{"id":930,"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=\/wp\/v2\/posts\/920\/revisions\/930"}],"wp:attachment":[{"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=920"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=920"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=920"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}