Skip to content

Commit de2c4e1

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 de1c8c8 commit de2c4e1

13 files changed

Lines changed: 295 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: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,18 @@
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'
22+
require 'zip'
2123

2224
module JavaBuildpack
2325
module Jre
2426

2527
# Encapsulates the detect, compile, and release functionality for selecting an OpenJDK-like JRE.
2628
class OpenJDKLike < JavaBuildpack::Component::VersionedDependencyComponent
29+
include Find
2730

2831
# Creates an instance
2932
#
@@ -33,15 +36,20 @@ def initialize(context)
3336
@component_name = self.class.to_s.space_case
3437
@configuration = context[:configuration]
3538
@droplet = context[:droplet]
39+
@logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger OpenJDKLike
3640

3741
@droplet.java_home.root = @droplet.sandbox
3842
end
3943

4044
# (see JavaBuildpack::Component::BaseComponent#detect)
4145
def detect
42-
@version, @uri = JavaBuildpack::Repository::ConfiguredItem.find_item(@component_name,
43-
@configuration)
46+
version = detect_compiled?(@configuration[KEY_VERSION]) ? compiled_version(@application.root) : VERSION_8
47+
configuration = { KEY_REPOSITORY_ROOT => @configuration[KEY_REPOSITORY_ROOT],
48+
KEY_VERSION => @configuration[KEY_VERSION][version] }
49+
50+
@version, @uri = JavaBuildpack::Repository::ConfiguredItem.find_item(@component_name, configuration)
4451
@droplet.java_home.version = @version
52+
4553
super
4654
end
4755

@@ -53,30 +61,96 @@ def compile
5361

5462
# (see JavaBuildpack::Component::BaseComponent#release)
5563
def release
64+
version = detect_compiled?(@configuration[KEY_VERSION]) ? compiled_version(@application.root) : VERSION_8
65+
5666
@droplet.java_opts
5767
.add_system_property('java.io.tmpdir', '$TMPDIR')
5868
.add_option('-XX:OnOutOfMemoryError', killjava)
59-
.concat memory
69+
.concat memory(version)
6070
end
6171

6272
private
6373

74+
CAFEBABE = 'cafebabe'.freeze
75+
76+
KEY_DETECT_COMPILED_VERSION = 'detect_compiled'.freeze
77+
6478
KEY_MEMORY_HEURISTICS = 'memory_heuristics'.freeze
6579

6680
KEY_MEMORY_SIZES = 'memory_sizes'.freeze
6781

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

70121
def killjava
71122
@droplet.sandbox + 'bin/killjava.sh'
72123
end
73124

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

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

82156
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)