1515# limitations under the License.
1616
1717require 'fileutils'
18+ require 'find'
1819require 'java_buildpack/component/versioned_dependency_component'
1920require 'java_buildpack/jre'
2021require 'java_buildpack/jre/memory/openjdk_memory_heuristic_factory'
22+ require 'zip'
2123
2224module 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
0 commit comments