|
| 1 | +tag: ready |
| 2 | +github_url: https://github.com/SAP/cf-cli-java-plugin |
| 3 | +tagline: Cloud Foundry CLI plugin to troubleshoot Java apps running on CF without SSH. Trigger heap |
| 4 | + dumps, thread dumps, and async-profiler or JFR recordings from the cf command line, with results |
| 5 | + streamed back to your machine. Also embeds jstall for full JVM inspection via `cf java jstall`. |
| 6 | +tagline_short: Trigger heap dumps, thread dumps, and profiles from the CF CLI — no SSH needed. |
| 7 | +when_to_use: |
| 8 | +- You run Java apps on Cloud Foundry and need heap dumps, thread dumps, or CPU profiles |
| 9 | +- You want jstall-style JVM inspection without SSH access to the container |
| 10 | +- You need to record JVM diagnostic data (status zip) for offline analysis |
| 11 | +when_not_to_use: |
| 12 | +- You are not using Cloud Foundry (use jstall directly for non-CF JVMs) |
| 13 | +- You need real-time continuous profiling rather than one-shot diagnostics |
| 14 | +related: |
| 15 | +- label: jstall |
| 16 | + url: https://github.com/parttimenerd/jstall |
| 17 | +links: |
| 18 | +- label: CF Plugin Registry ↗ |
| 19 | + url: https://plugins.cloudfoundry.org/ |
| 20 | +install: |
| 21 | +- label: Latest (manual) |
| 22 | + lang: bash |
| 23 | + code: | |
| 24 | + # Pick the binary for your platform: |
| 25 | + cf install-plugin https://github.com/SAP/cf-cli-java-plugin/releases/latest/download/cf-cli-java-plugin-macos-arm64 |
| 26 | + # linux-amd64 / linux-arm64 / windows-amd64 also available |
| 27 | +- label: CF Community |
| 28 | + lang: bash |
| 29 | + code: | |
| 30 | + cf install-plugin -r CF-Community "java" |
| 31 | + # Note: community repo lags behind GitHub releases |
| 32 | +usage: |
| 33 | +- label: Quick start |
| 34 | + lang: bash |
| 35 | + code: | |
| 36 | + cf java heap-dump my-app |
| 37 | + cf java thread-dump my-app |
| 38 | + cf java jstall my-app |
| 39 | +how_to: |
| 40 | +- title: My CF app is not responding — find what it is stuck on |
| 41 | + body: | |
| 42 | + Run `jstall` first — it detects deadlocks, identifies BLOCKED threads, and shows what |
| 43 | + each thread is waiting for: |
| 44 | + ```bash |
| 45 | + cf java jstall $APP_NAME |
| 46 | + ``` |
| 47 | + If there is a deadlock, it will be listed at the top with the cycle of threads and monitors. |
| 48 | + For a focused deadlock check only: |
| 49 | + ```bash |
| 50 | + cf java jstall $APP_NAME --args 'deadlock all' |
| 51 | + ``` |
| 52 | + If no deadlock, look for threads in `BLOCKED` state and the monitor they are waiting on. |
| 53 | + The thread that *holds* that monitor is the bottleneck. For a plain thread dump: |
| 54 | + ```bash |
| 55 | + cf java thread-dump $APP_NAME |
| 56 | + ``` |
| 57 | +
|
| 58 | +- title: My CF app is using too much CPU |
| 59 | + body: | |
| 60 | + `most-work` takes repeated thread dumps and ranks threads by on-CPU frequency — |
| 61 | + no async-profiler needed: |
| 62 | + ```bash |
| 63 | + cf java jstall $APP_NAME --args 'most-work --dumps 5 all' |
| 64 | + ``` |
| 65 | + For a proper CPU flame graph (slower, but much more detail): |
| 66 | + ```bash |
| 67 | + cf java jstall $APP_NAME --args 'flame all' |
| 68 | + # Downloads an HTML flamegraph to your current directory |
| 69 | + ``` |
| 70 | + Or use the two-step async-profiler approach if you want to capture during a specific window: |
| 71 | + ```bash |
| 72 | + cf java asprof-start-cpu $APP_NAME |
| 73 | + # reproduce the slow operation or wait 30–60 s |
| 74 | + cf java asprof-stop $APP_NAME |
| 75 | + # Downloads $APP_NAME-asprof-<random>.jfr — open in JDK Mission Control |
| 76 | + ``` |
| 77 | +
|
| 78 | +- title: My CF app crashed with OutOfMemoryError — take a heap dump |
| 79 | + body: | |
| 80 | + Take a heap dump from the running (or restarted) instance and download it: |
| 81 | + ```bash |
| 82 | + cf java heap-dump $APP_NAME |
| 83 | + # Downloads $APP_NAME-heapdump-<random>.hprof to current directory |
| 84 | + ``` |
| 85 | + Analyse with hprof-analyzer for Leak Suspects and Top Consumers: |
| 86 | + ```bash |
| 87 | + hprof-analyzer $APP_NAME-heapdump-*.hprof report.html |
| 88 | + # Open report.html → "Leak Suspects" and "Top Consumers" tabs |
| 89 | + ``` |
| 90 | + **Note:** requires jmap, which is not bundled by default in the CF Java Buildpack. |
| 91 | + Add a full JDK via `JBP_CONFIG_OPEN_JDK_JRE: '[jre: {version: 21.+}, jdk: {include: true}]'` |
| 92 | + to your app's environment if you see a "jmap not found" error. |
| 93 | +
|
| 94 | +- title: Take a heap dump from a running CF app |
| 95 | + body: | |
| 96 | + ```bash |
| 97 | + cf java heap-dump $APP_NAME |
| 98 | + ``` |
| 99 | + Downloads `$APP_NAME-heapdump-<random>.hprof` to your current directory. |
| 100 | + Open it in VisualVM, Eclipse MAT, or IntelliJ's heap analyzer. |
| 101 | +
|
| 102 | + **Note:** requires jmap, which is not bundled by default in the CF Java Buildpack. |
| 103 | + Add a full JDK via `JBP_CONFIG_OPEN_JDK_JRE: '[jre: {version: 21.+}, jdk: {include: true}]'` |
| 104 | + to your app's environment if you see a "jmap not found" error. |
| 105 | +
|
| 106 | +- title: Get a thread dump and spot deadlocks |
| 107 | + body: | |
| 108 | + ```bash |
| 109 | + cf java thread-dump $APP_NAME |
| 110 | + ``` |
| 111 | + Prints the full thread dump to stdout. To save it: |
| 112 | + ```bash |
| 113 | + cf java thread-dump $APP_NAME > thread-dump.txt |
| 114 | + ``` |
| 115 | + For a richer analysis including deadlock detection, hot threads, and lock graphs, use jstall: |
| 116 | + ```bash |
| 117 | + cf java jstall $APP_NAME --args 'deadlock all' |
| 118 | + ``` |
| 119 | +
|
| 120 | +- title: Profile CPU usage with async-profiler |
| 121 | + body: | |
| 122 | + ```bash |
| 123 | + cf java asprof-start-cpu $APP_NAME |
| 124 | + # reproduce the slow operation or wait 30–60 s |
| 125 | + cf java asprof-stop $APP_NAME |
| 126 | + # Downloads $APP_NAME-asprof-<random>.jfr |
| 127 | + ``` |
| 128 | + Open the `.jfr` file in JDK Mission Control or IntelliJ to view the flame graph. |
| 129 | + For a one-shot flame graph without manual start/stop, use jstall: |
| 130 | + ```bash |
| 131 | + cf java jstall $APP_NAME --args 'flame all' |
| 132 | + ``` |
| 133 | +
|
| 134 | +- title: Record a full diagnostic snapshot for offline analysis |
| 135 | + body: | |
| 136 | + ```bash |
| 137 | + # Record everything (thread dump, heap histogram, jcmd output) into a zip: |
| 138 | + cf java record-status $APP_NAME |
| 139 | +
|
| 140 | + # Include JFR recording and flame graph (slower, larger): |
| 141 | + cf java record-status $APP_NAME --full |
| 142 | +
|
| 143 | + # Replay the zip locally with jstall: |
| 144 | + jstall -f $APP_NAME-status.zip status all |
| 145 | + jstall -f $APP_NAME-status.zip threads all |
| 146 | + ``` |
| 147 | + Useful for sharing diagnostics with teammates or filing bug reports without |
| 148 | + giving them CF access. |
| 149 | +
|
| 150 | +- title: Inspect a Cloud Foundry app with jstall |
| 151 | + body: | |
| 152 | + The plugin embeds jstall directly — no separate installation needed: |
| 153 | + ```bash |
| 154 | + # Full status report (deadlock detection, hot threads, etc.): |
| 155 | + cf java jstall $APP_NAME |
| 156 | +
|
| 157 | + # Run a specific jstall subcommand: |
| 158 | + cf java jstall $APP_NAME --args 'most-work --dumps 3 all' |
| 159 | + cf java jstall $APP_NAME --args 'flame all' |
| 160 | + ``` |
| 161 | + To use a newer jstall version than the one bundled in the plugin, |
| 162 | + use jstall's own `--cf` option instead: |
| 163 | + ```bash |
| 164 | + jstall --cf $APP_NAME status all |
| 165 | + ``` |
| 166 | +note: Requires cf ssh to be enabled on the app (`cf enable-ssh my-app`, then restart). |
| 167 | + The heap-dump command additionally needs jmap — see the How To entry above if it is missing. |
0 commit comments