Skip to content

Commit 5f5149e

Browse files
Adding Support for JaCoCo Agent Configuration Options
This change introduces support for additional configuration options for the JaCoCo agent, enhancing its flexibility and usability. These changes were made to be backwards compatible, ensuring that existing configurations continue to work without modification. Added optional configuration options: - destfile - append - exclclassloader - inclbootstrapclasses - inclnolocationclasses - sessionid (defaulted to instance uuid) - dumponexit - classdumpdir - jmx Issue: #1116
1 parent 1c46ab6 commit 5f5149e

File tree

3 files changed

+105
-20
lines changed

3 files changed

+105
-20
lines changed

docs/framework-jacoco_agent.md

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,22 @@ Users may optionally provide their own JaCoCo service. A user-provided JaCoCo se
2121

2222
The credential payload of the service may contain the following entries:
2323

24-
| Name | Description
25-
| ---- | -----------
26-
| `address` | The host for the agent to connect to or listen on
27-
| `excludes` | (Optional) A list of class names that should be excluded from execution analysis. The list entries are separated by a colon (:) and may use wildcard characters (* and ?).
28-
| `includes` | (Optional) A list of class names that should be included in execution analysis. The list entries are separated by a colon (:) and may use wildcard characters (* and ?).
29-
| `port` | (Optional) The port for the agent to connect to or listen on
30-
| `output` | (Optional) The mode for the agent. Possible values are either tcpclient (default) or tcpserver.
24+
| Name | Description
25+
|------------------------|------------
26+
| `address` | The host for the agent to connect to or listen on.
27+
| `destfile` | (Optional) The path to the file where execution data is written. Default is `jacoco.exec`.
28+
| `sessionid` | (Optional) The identifier for the coverage session. Useful for distinguishing between different test runs.
29+
| `append` | (Optional) If set to `true`, coverage data is appended to the existing file. Default is `false`.
30+
| `includes` | (Optional) A list of class names to include in execution analysis. Entries are separated by a colon (`:`) and may use wildcards (`*`, `?`).
31+
| `excludes` | (Optional) A list of class names to exclude from execution analysis. Entries are separated by a colon (`:`) and may use wildcards (`*`, `?`).
32+
| `exclclassloader` | (Optional) A list of class loader names to exclude from instrumentation. Entries are separated by a colon (`:`).
33+
| `inclbootstrapclasses` | (Optional) If set to `true`, includes bootstrap classes for instrumentation. Default is `false`.
34+
| `inclnolocationclasses`| (Optional) If set to `true`, includes classes without a location for instrumentation. Default is `false`.
35+
| `dumponexit` | (Optional) If set to `true`, coverage data is written on JVM shutdown. Default is `true`.
36+
| `output` | (Optional) The mode for the agent. Possible values are `tcpclient` (default) or `tcpserver`.
37+
| `port` | (Optional) The port for the agent to connect to or listen on.
38+
| `classdumpdir` | (Optional) The directory where class files are dumped if class dumping is enabled.
39+
| `jmx` | (Optional) If set to `true`, enables JMX control for the agent. Default is `false`.
3140

3241
## Configuration
3342
For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][].

lib/java_buildpack/framework/jacoco_agent.rb

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,8 @@ def compile
3131

3232
# (see JavaBuildpack::Component::BaseComponent#release)
3333
def release
34-
credentials = @application.services.find_service(FILTER, ADDRESS)['credentials']
35-
properties = {
36-
'address' => credentials[ADDRESS],
37-
'output' => 'tcpclient',
38-
'sessionid' => '$CF_INSTANCE_GUID'
39-
}
40-
41-
properties['excludes'] = credentials['excludes'] if credentials.key? 'excludes'
42-
properties['includes'] = credentials['includes'] if credentials.key? 'includes'
43-
properties['port'] = credentials['port'] if credentials.key? 'port'
44-
properties['output'] = credentials['output'] if credentials.key? 'output'
45-
46-
@droplet.java_opts.add_javaagent_with_props(@droplet.sandbox + 'jacocoagent.jar', properties)
34+
@droplet.java_opts.add_javaagent_with_props(@droplet.sandbox + 'jacocoagent.jar',
35+
build_properties(service_credentials))
4736
end
4837

4938
protected
@@ -59,6 +48,51 @@ def supports?
5948

6049
private_constant :ADDRESS, :FILTER
6150

51+
OPTIONAL_PROPS = {
52+
'excludes' => nil,
53+
'includes' => nil,
54+
'port' => nil,
55+
'destfile' => nil,
56+
'append' => nil,
57+
'exclclassloader' => nil,
58+
'inclbootstrapclasses' => nil,
59+
'inclnolocationclasses' => nil,
60+
'dumponexit' => nil,
61+
'classdumpdir' => nil,
62+
'jmx' => nil
63+
}.freeze
64+
65+
private_constant :ADDRESS, :FILTER, :OPTIONAL_PROPS
66+
67+
private
68+
69+
def service_credentials
70+
@application.services.find_service(FILTER, ADDRESS)['credentials']
71+
end
72+
73+
def build_properties(credentials)
74+
properties = base_properties(credentials)
75+
properties.merge!(optional_properties(credentials))
76+
end
77+
78+
def base_properties(credentials)
79+
{
80+
'address' => credentials[ADDRESS],
81+
'output' => credentials['output'] || 'tcpclient',
82+
'sessionid' => credentials['sessionid'] || '$CF_INSTANCE_GUID'
83+
}
84+
end
85+
86+
def optional_properties(credentials)
87+
opts = {}
88+
OPTIONAL_PROPS.each_key do |key|
89+
next unless credentials.key?(key)
90+
91+
opts[key] = credentials[key]
92+
end
93+
opts
94+
end
95+
6296
end
6397

6498
end

spec/java_buildpack/framework/jacoco_agent_spec.rb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,42 @@
3333
allow(services).to receive(:one_service?).with(/jacoco/, 'address').and_return(true)
3434
end
3535

36+
let(:extended_credentials) do
37+
{ 'address' => 'ext-address',
38+
'output' => 'tcpserver',
39+
'sessionid' => 'ext-session',
40+
'excludes' => 'ex.*',
41+
'includes' => 'in.*',
42+
'port' => 7654,
43+
'destfile' => 'custom.exec',
44+
'append' => 'false',
45+
'exclclassloader' => 'loader.*',
46+
'inclbootstrapclasses' => 'true',
47+
'inclnolocationclasses' => 'true',
48+
'dumponexit' => 'false',
49+
'classdumpdir' => 'dumpdir',
50+
'jmx' => 'true' }
51+
end
52+
53+
let(:extended_expected) do
54+
[
55+
'-javaagent:$PWD/.java-buildpack/jacoco_agent/jacocoagent.jar=address=ext-address',
56+
'output=tcpserver',
57+
'sessionid=ext-session',
58+
'excludes=ex.*',
59+
'includes=in.*',
60+
'port=7654',
61+
'destfile=custom.exec',
62+
'append=false',
63+
'exclclassloader=loader.*',
64+
'inclbootstrapclasses=true',
65+
'inclnolocationclasses=true',
66+
'dumponexit=false',
67+
'classdumpdir=dumpdir',
68+
'jmx=true'
69+
].join(',')
70+
end
71+
3672
it 'detects with jacoco service' do
3773
expect(component.detect).to eq("jacoco-agent=#{version}")
3874
end
@@ -68,6 +104,12 @@
68104
'excludes=test-excludes,includes=test-includes,port=6300')
69105
end
70106

107+
it 'updates JAVA_OPTS with extended options' do
108+
allow(services).to receive(:find_service).and_return('credentials' => extended_credentials)
109+
component.release
110+
expect(java_opts).to include(extended_expected)
111+
end
112+
71113
end
72114

73115
end

0 commit comments

Comments
 (0)