Skip to content

Commit ed75d7b

Browse files
Christopher Frostnebhale
authored andcommitted
Auto detect Java major version
The commit adds the ability to turn on Java version detection. This will scan the application to detect the major version of Java that should be used for the application and then refer to the config file for the exact version to use. [#71382852]
1 parent bc4249b commit ed75d7b

13 files changed

Lines changed: 294 additions & 18 deletions

File tree

.idea/dictionaries/cgfrost.xml

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/open_jdk_jre.yml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,21 @@
1414
# limitations under the License.
1515

1616
# Configuration for JRE repositories keyed by vendor
17-
# To go back to Java 7, permgen should be used instead of metaspace. Please see the documentation for more detail.
17+
# Pre Java 1.8, permgen was used instead of metaspace, the buildpack will consume the configuration as appropriate.
18+
# Please see the documentation for more detail.
1819
---
1920
repository_root: "{default.repository.root}/openjdk/{platform}/{architecture}"
20-
version: 1.8.0_+
21+
version:
22+
detect_compiled: enabled
23+
8: 1.8.0_+
24+
7: 1.7.0_+
25+
6: 1.6.0_+
2126
memory_sizes:
2227
metaspace: 64m..
23-
# permgen: 64m..
28+
permgen: 64m..
2429
memory_heuristics:
2530
heap: 75
2631
metaspace: 10
27-
# permgen: 10
32+
permgen: 10
2833
stack: 5
2934
native: 10

config/oracle_jre.yml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,24 @@
1414
# limitations under the License.
1515

1616
# Configuration for JRE repositories keyed by vendor
17-
# Pre Java 1.8, permgen was used instead of metaspace. Please see the documentation for more detail.
17+
# Pre Java 1.8, permgen was used instead of metaspace, the buildpack will consume the configuration as appropriate.
18+
# Please see the documentation for more detail.
1819
---
1920
# You must specify a the repository root of an Oracle JRE repository. Please see the documentation for more detail.
2021
# e.g. repository_root: "http://example.com/oracle-jre/{platform}/{architecture}"
2122

2223
repository_root: ""
23-
version: 1.8.0_+
24+
version:
25+
detect_compiled: enabled
26+
8: 1.8.0_+
27+
7: 1.7.0_+
28+
6: 1.6.0_+
2429
memory_sizes:
2530
metaspace: 64m..
26-
# permgen: 64m..
31+
permgen: 64m..
2732
memory_heuristics:
2833
heap: 75
2934
metaspace: 10
30-
# permgen: 10
35+
permgen: 10
3136
stack: 5
3237
native: 10

java-buildpack.iml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@
271271
<orderEntry type="library" scope="PROVIDED" name="addressable (v2.3.6, rbenv: 1.9.3-p551) [gem]" level="application" />
272272
<orderEntry type="library" scope="PROVIDED" name="ast (v2.0.0, rbenv: 1.9.3-p551) [gem]" level="application" />
273273
<orderEntry type="library" scope="PROVIDED" name="astrolabe (v1.3.0, rbenv: 1.9.3-p551) [gem]" level="application" />
274-
<orderEntry type="library" scope="PROVIDED" name="bundler (v1.7.8, rbenv: 1.9.3-p551) [gem]" level="application" />
274+
<orderEntry type="library" scope="PROVIDED" name="bundler (v1.7.11, rbenv: 1.9.3-p551) [gem]" level="application" />
275275
<orderEntry type="library" scope="PROVIDED" name="codeclimate-test-reporter (v0.4.3, rbenv: 1.9.3-p551) [gem]" level="application" />
276276
<orderEntry type="library" scope="PROVIDED" name="crack (v0.4.2, rbenv: 1.9.3-p551) [gem]" level="application" />
277277
<orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.2.5, rbenv: 1.9.3-p551) [gem]" level="application" />
@@ -281,13 +281,13 @@
281281
<orderEntry type="library" scope="PROVIDED" name="powerpack (v0.0.9, rbenv: 1.9.3-p551) [gem]" level="application" />
282282
<orderEntry type="library" scope="PROVIDED" name="rainbow (v2.0.0, rbenv: 1.9.3-p551) [gem]" level="application" />
283283
<orderEntry type="library" scope="PROVIDED" name="rake (v10.4.2, rbenv: 1.9.3-p551) [gem]" level="application" />
284-
<orderEntry type="library" scope="PROVIDED" name="redcarpet (v3.2.1, rbenv: 1.9.3-p551) [gem]" level="application" />
284+
<orderEntry type="library" scope="PROVIDED" name="redcarpet (v3.2.2, rbenv: 1.9.3-p551) [gem]" level="application" />
285285
<orderEntry type="library" scope="PROVIDED" name="rspec (v3.1.0, rbenv: 1.9.3-p551) [gem]" level="application" />
286286
<orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.1.7, rbenv: 1.9.3-p551) [gem]" level="application" />
287287
<orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.1.2, rbenv: 1.9.3-p551) [gem]" level="application" />
288288
<orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.1.3, rbenv: 1.9.3-p551) [gem]" level="application" />
289289
<orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.1.2, rbenv: 1.9.3-p551) [gem]" level="application" />
290-
<orderEntry type="library" scope="PROVIDED" name="rubocop (v0.27.1, rbenv: 1.9.3-p551) [gem]" level="application" />
290+
<orderEntry type="library" scope="PROVIDED" name="rubocop (v0.28.0, rbenv: 1.9.3-p551) [gem]" level="application" />
291291
<orderEntry type="library" scope="PROVIDED" name="rubocop-rspec (v1.2.1, rbenv: 1.9.3-p551) [gem]" level="application" />
292292
<orderEntry type="library" scope="PROVIDED" name="ruby-progressbar (v1.7.0, rbenv: 1.9.3-p551) [gem]" level="application" />
293293
<orderEntry type="library" scope="PROVIDED" name="rubyzip (v1.1.6, rbenv: 1.9.3-p551) [gem]" level="application" />

lib/java_buildpack/jre/open_jdk_like.rb

Lines changed: 80 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
# limitations under the License.
1616

1717
require 'fileutils'
18+
require 'find'
1819
require 'java_buildpack/component/versioned_dependency_component'
1920
require 'java_buildpack/jre'
2021
require 'java_buildpack/jre/memory/openjdk_memory_heuristic_factory'
@@ -24,6 +25,7 @@ module Jre
2425

2526
# Encapsulates the detect, compile, and release functionality for selecting an OpenJDK-like JRE.
2627
class OpenJDKLike < JavaBuildpack::Component::VersionedDependencyComponent
28+
include Find
2729

2830
# Creates an instance
2931
#
@@ -33,15 +35,20 @@ def initialize(context)
3335
@component_name = self.class.to_s.space_case
3436
@configuration = context[:configuration]
3537
@droplet = context[:droplet]
38+
@logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger OpenJDKLike
3639

3740
@droplet.java_home.root = @droplet.sandbox
3841
end
3942

4043
# (see JavaBuildpack::Component::BaseComponent#detect)
4144
def detect
42-
@version, @uri = JavaBuildpack::Repository::ConfiguredItem.find_item(@component_name,
43-
@configuration)
45+
version = detect_compiled?(@configuration[KEY_VERSION]) ? compiled_version(@application.root) : VERSION_8
46+
configuration = { KEY_REPOSITORY_ROOT => @configuration[KEY_REPOSITORY_ROOT],
47+
KEY_VERSION => @configuration[KEY_VERSION][version] }
48+
49+
@version, @uri = JavaBuildpack::Repository::ConfiguredItem.find_item(@component_name, configuration)
4450
@droplet.java_home.version = @version
51+
4552
super
4653
end
4754

@@ -53,30 +60,96 @@ def compile
5360

5461
# (see JavaBuildpack::Component::BaseComponent#release)
5562
def release
63+
version = detect_compiled?(@configuration[KEY_VERSION]) ? compiled_version(@application.root) : VERSION_8
64+
5665
@droplet.java_opts
5766
.add_system_property('java.io.tmpdir', '$TMPDIR')
5867
.add_option('-XX:OnOutOfMemoryError', killjava)
59-
.concat memory
68+
.concat memory(version)
6069
end
6170

6271
private
6372

73+
CAFEBABE = 'cafebabe'.freeze
74+
75+
KEY_DETECT_COMPILED_VERSION = 'detect_compiled'.freeze
76+
6477
KEY_MEMORY_HEURISTICS = 'memory_heuristics'.freeze
6578

6679
KEY_MEMORY_SIZES = 'memory_sizes'.freeze
6780

68-
private_constant :KEY_MEMORY_HEURISTICS, :KEY_MEMORY_SIZES
81+
KEY_REPOSITORY_ROOT = 'repository_root'.freeze
82+
83+
KEY_VERSION = 'version'.freeze
84+
85+
VERSION_6 = 6.freeze
86+
87+
VERSION_7 = 7.freeze
88+
89+
VERSION_8 = 8.freeze
90+
91+
private_constant :CAFEBABE, :KEY_DETECT_COMPILED_VERSION, :KEY_MEMORY_HEURISTICS, :KEY_MEMORY_SIZES,
92+
:KEY_REPOSITORY_ROOT, :KEY_VERSION, :VERSION_6, :VERSION_7, :VERSION_8
93+
94+
def class?(path)
95+
File.extname(path) == '.class'
96+
end
97+
98+
def class_file_format(path)
99+
bits = File.open(path).read.unpack('H*')[0]
100+
@logger.debug { "Scanning #{path}: #{bits[0, 8]}/#{bits[14, 2]}" }
101+
102+
Integer(bits[14, 2]) if magic_number?(bits)
103+
end
104+
105+
def compiled_version(root)
106+
@logger.debug { 'Detecting compiled version' }
107+
108+
versions = find(root.to_path).map do |child|
109+
next if File.directory?(child) || !class?(child)
110+
class_file_format child
111+
end
112+
113+
version versions.max_by(&:to_i)
114+
end
115+
116+
def detect_compiled?(configuration)
117+
configuration[KEY_DETECT_COMPILED_VERSION] == 'enabled'
118+
end
69119

70120
def killjava
71121
@droplet.sandbox + 'bin/killjava.sh'
72122
end
73123

74-
def memory
75-
sizes = @configuration[KEY_MEMORY_SIZES] || {}
76-
heuristics = @configuration[KEY_MEMORY_HEURISTICS] || {}
124+
def magic_number?(bits)
125+
bits[0, 8] == CAFEBABE
126+
end
127+
128+
def memory(version)
129+
sizes = @configuration[KEY_MEMORY_SIZES] ? @configuration[KEY_MEMORY_SIZES].clone : {}
130+
heuristics = @configuration[KEY_MEMORY_HEURISTICS] ? @configuration[KEY_MEMORY_HEURISTICS].clone : {}
131+
132+
if version < VERSION_8
133+
heuristics.delete 'metaspace'
134+
sizes.delete 'metaspace'
135+
else
136+
heuristics.delete 'permgen'
137+
sizes.delete 'permgen'
138+
end
139+
77140
OpenJDKMemoryHeuristicFactory.create_memory_heuristic(sizes, heuristics, @version).resolve
78141
end
79142

143+
def version(format)
144+
if format == 32
145+
VERSION_6
146+
elsif format == 33
147+
VERSION_7
148+
else
149+
VERSION_8
150+
end
151+
end
152+
80153
end
81154

82155
end
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Manifest-Version: 1.0
2+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Manifest-Version: 1.0
2+

0 commit comments

Comments
 (0)