Skip to content

Commit 13055ac

Browse files
authored
chore: add .tool.yaml metadata (#55)
* chore: add .tool.yaml metadata * docs: add symptom-driven how-tos (unresponsive, high CPU, OOM) * docs: add Common Tasks section (unresponsive, high CPU, OOM)
1 parent c82bdc5 commit 13055ac

2 files changed

Lines changed: 235 additions & 0 deletions

File tree

.tool.yaml

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
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.

README.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,74 @@ cf install-plugin https://github.com/SAP/cf-cli-java-plugin/releases/download/sn
6969
cf install-plugin https://github.com/SAP/cf-cli-java-plugin/releases/download/snapshot/cf-cli-java-plugin-linux-arm64
7070
```
7171

72+
## Common Tasks
73+
74+
### My CF app is not responding — find what it is stuck on
75+
76+
Run `jstall` first — it detects deadlocks, identifies BLOCKED threads, and shows what
77+
each thread is waiting for:
78+
79+
```bash
80+
cf java jstall $APP_NAME
81+
```
82+
83+
If there is a deadlock, it will be listed at the top with the cycle of threads and monitors.
84+
For a focused deadlock check only:
85+
86+
```bash
87+
cf java jstall $APP_NAME --args 'deadlock all'
88+
```
89+
90+
If no deadlock, look for threads in `BLOCKED` state and the monitor they are waiting on.
91+
The thread that *holds* that monitor is the bottleneck. For a plain thread dump:
92+
93+
```bash
94+
cf java thread-dump $APP_NAME
95+
```
96+
97+
### My CF app is using too much CPU
98+
99+
`most-work` takes repeated thread dumps and ranks threads by on-CPU frequency —
100+
no async-profiler needed:
101+
102+
```bash
103+
cf java jstall $APP_NAME --args 'most-work --dumps 5 all'
104+
```
105+
106+
For a proper CPU flame graph (slower, but much more detail):
107+
108+
```bash
109+
cf java jstall $APP_NAME --args 'flame all'
110+
# Downloads an HTML flamegraph to your current directory
111+
```
112+
113+
Or use the two-step async-profiler approach to capture a specific window:
114+
115+
```bash
116+
cf java asprof-start-cpu $APP_NAME
117+
# reproduce the slow operation or wait 30–60 s
118+
cf java asprof-stop $APP_NAME
119+
# Downloads $APP_NAME-asprof-<random>.jfr — open in JDK Mission Control
120+
```
121+
122+
### My CF app crashed with OutOfMemoryError — take a heap dump
123+
124+
Take a heap dump from the running (or restarted) instance and download it:
125+
126+
```bash
127+
cf java heap-dump $APP_NAME
128+
# Downloads $APP_NAME-heapdump-<random>.hprof to current directory
129+
```
130+
131+
Analyse with [hprof-analyzer](https://github.com/parttimenerd/hprof-analyzer) for Leak Suspects and Top Consumers:
132+
133+
```bash
134+
hprof-analyzer $APP_NAME-heapdump-*.hprof report.html
135+
# Open report.html → "Leak Suspects" and "Top Consumers" tabs
136+
```
137+
138+
**Note:** requires jmap — see [Prerequisites](#prerequisites) if you see a "jmap not found" error.
139+
72140
## Usage
73141

74142
### Prerequisites

0 commit comments

Comments
 (0)