Skip to content

Commit 5bf6497

Browse files
bharathappalinebhale
authored andcommitted
IBM JRE
This change adds the IBM JRE to the collection of available JREs in the buildpack. [cloudfoundry#427]
1 parent ebbbda4 commit 5bf6497

10 files changed

Lines changed: 486 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi
9999
* [OpenJDK](docs/jre-open_jdk_jre.md) ([Configuration](docs/jre-open_jdk_jre.md#configuration))
100100
* [Oracle](docs/jre-oracle_jre.md) ([Configuration](docs/jre-oracle_jre.md#configuration))
101101
* [Azul Zulu](docs/jre-zulu_jre.md) ([Configuration](docs/jre-zulu_jre.md#configuration))
102+
* [IBM® SDK, Java™ Technology Edition](docs/jre-ibm_jre.md) ([Configuration](docs/jre-ibm_jre.md#configuration))
102103
* [Extending](docs/extending.md)
103104
* [Application](docs/extending-application.md)
104105
* [Droplet](docs/extending-droplet.md)

config/components.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ containers:
2929
# In order to use Zulu JREs instead of OpenJDK, you must comment out the OpenJDK line and uncomment the Zulu line.
3030
# Please see the documentation for more detail.
3131
jres:
32+
# - "JavaBuildpack::Jre::IbmJRE"
3233
- "JavaBuildpack::Jre::OpenJdkJRE"
3334
# - "JavaBuildpack::Jre::OracleJRE"
3435
# - "JavaBuildpack::Jre::ZuluJRE"

config/ibm_jre.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Cloud Foundry Java Buildpack
2+
# Copyright 2017 the original author or authors.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
17+
# Configuration for JRE repository
18+
---
19+
jre:
20+
version: 1.8.+
21+
repository_root: "https://raw.githubusercontent.com/ibmruntimes/ci.docker/master/ibmjava/meta/jre/linux/x86_64/"
22+
heap_ratio: 0.75
23+
jvmkill_agent:
24+
version: 1.+
25+
repository_root: "https://raw.githubusercontent.com/ibmruntimes/jvmkill/jvmkill-ibmagent/jvmkill-agent/"

docs/jre-ibm_jre.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
## IBM JRE
2+
IBM JRE provides IBM® SDK, Java™ Technology Edition, Version 8. Unless otherwise configured, the version of Java that will be used is specified in [`config/ibm_jre.yml`][]. See the license section for restrictions that relate to the use of this image. For more information about IBM® SDK, Java™ Technology Edition and API documentation, see the [IBM Knowledge Center][].
3+
4+
### License
5+
Licenses for the products installed within the buildpack:
6+
7+
IBM® SDK, Java™ Technology Edition, Version 8: [International License Agreement for Non-Warranted Programs][].
8+
9+
## Configuration
10+
For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][].
11+
12+
The JRE can be configured by modifying the [`config/ibm_jre.yml`][] file in the buildpack fork. The JRE uses the [`Repository` utility support][repositories] and so, it supports the [version syntax][] defined there.
13+
14+
To use IBM JRE instead of OpenJDK without forking java-buildpack, set environment variable:
15+
16+
`cf set-env <app_name> JBP_CONFIG_COMPONENTS '{jres: ["JavaBuildpack::Jre::IbmJRE"]}'`
17+
18+
`cf restage <app_name>`
19+
20+
| Name | Description
21+
| ---- | -----------
22+
| `repository_root` | The URL of the IBM JRE repository index ([details][repositories]).
23+
| `version` | The version of Java runtime to use.
24+
25+
### TLS Options
26+
It is recommended to use the following Transport Layer Security (TLS) options for IBM JRE version 8 and above:
27+
28+
`cf set-env <app_name> JAVA_OPTS '-Dcom.ibm.jsse2.overrideDefaultTLS=true'`
29+
30+
### Additional Resources
31+
The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/ibm_jre` directory in the buildpack fork.
32+
33+
#### Custom CA Certificates
34+
To add custom SSL certificates, add your `cacerts` file to `resources/ibm_jre/jre/lib/security/cacerts`. This file will be overlayed onto the IBM JRE distribution.
35+
36+
### Memory
37+
The total available memory for the application's container is specified when an application is pushed.The Java buildpack uses this value to control the JRE's use of various regions of memory and logs the JRE memory settings when the application starts or restarts.
38+
39+
Note: If the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings the next time the application is started.
40+
41+
#### Total Memory
42+
The user can change the container's total memory available to influence the JRE memory settings. Unless the user specifies the heap size Java option (`-Xmx`), increasing or decreasing the total memory available results in the heap size setting increasing or decreasing by a corresponding amount.
43+
44+
#### Memory Calculation
45+
The user can configure the desired heap ratio (`-Xmx`) by changing the `heap_ratio` attribute under `jre` in [`config/ibm_jre.yml`][] and the buildpack calculates the `-Xmx Memory Setting` based on the total memory available.
46+
47+
The container's total memory is logged during `cf push` and `cf scale`, for example:
48+
```
49+
state since cpu memory disk details
50+
#0 running 2017-04-10 02:20:03 PM 0.0% 896K of 1G 1.3M of 1G
51+
```
52+
53+
[`config/components.yml`]: ../config/components.yml
54+
[`config/ibm_jre.yml`]: ../config/ibm_jre.yml
55+
[Configuration and Extension]: ../README.md#configuration-and-extension
56+
[repositories]: extending-repositories.md
57+
[version syntax]: extending-repositories.md#version-syntax-and-ordering
58+
[IBM Knowledge Center]: http://www.ibm.com/support/knowledgecenter/SSYKE2/welcome_javasdk_family.html
59+
[International License Agreement for Non-Warranted Programs]: http://www14.software.ibm.com/cgi-bin/weblap/lap.pl?la_formnum=&li_formnum=L-PMAA-A3Z8P2&title=IBM%AE+SDK%2C+Java%99+Technology+Edition%2C+Version+8.0&l=en

lib/java_buildpack/jre/ibm_jre.rb

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Cloud Foundry Java Buildpack
2+
# Copyright 2017 the original author or authors.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
require 'java_buildpack/component/modular_component'
17+
require 'java_buildpack/jre'
18+
require 'java_buildpack/jre/ibm_jre_initializer'
19+
require 'java_buildpack/jre/jvmkill_agent'
20+
require 'java_buildpack/jre/open_jdk_like_security_providers'
21+
22+
module JavaBuildpack
23+
module Jre
24+
25+
# Encapsulates the detect, compile, and release functionality for selecting a JRE.
26+
class IbmJRE < JavaBuildpack::Component::ModularComponent
27+
28+
protected
29+
30+
# (see JavaBuildpack::Component::ModularComponent#command)
31+
def command
32+
# no command need to be executed
33+
end
34+
35+
# (see JavaBuildpack::Component::ModularComponent#sub_components)
36+
def sub_components(context)
37+
[
38+
IbmJreInitializer.new(sub_configuration_context(context, 'jre')
39+
.merge(component_name: self.class.to_s.space_case)),
40+
JvmkillAgent.new(sub_configuration_context(context, 'jvmkill_agent')),
41+
OpenJDKLikeSecurityProviders.new(context)
42+
]
43+
end
44+
45+
# (see JavaBuildpack::Component::ModularComponent#supports?)
46+
def supports?
47+
true
48+
end
49+
50+
end
51+
52+
end
53+
end
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
# Cloud Foundry Java Buildpack
2+
# Copyright 2017 the original author or authors.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
require 'digest'
17+
require 'fileutils'
18+
require 'java_buildpack/component/versioned_dependency_component'
19+
require 'java_buildpack/jre'
20+
require 'java_buildpack/util/tokenized_version'
21+
22+
module JavaBuildpack
23+
module Jre
24+
25+
# Encapsulates the detect, compile, and release functionality for selecting a JRE.
26+
class IbmJreInitializer < JavaBuildpack::Component::VersionedDependencyComponent
27+
28+
# Creates an instance
29+
#
30+
# @param [Hash] context a collection of utilities used the component
31+
def initialize(context)
32+
@application = context[:application]
33+
@component_name = context[:component_name]
34+
@configuration = context[:configuration]
35+
@droplet = context[:droplet]
36+
37+
@droplet.java_home.root = @droplet.sandbox + 'jre/'
38+
end
39+
40+
# (see JavaBuildpack::Component::BaseComponent#detect)
41+
def detect
42+
@version, @uri = JavaBuildpack::Repository::ConfiguredItem.find_item(@component_name,
43+
@configuration)
44+
@droplet.java_home.version = @version
45+
super
46+
end
47+
48+
# (see JavaBuildpack::Component::BaseComponent#compile)
49+
def compile
50+
download(@version, @uri, @component_name) do |file|
51+
with_timing "Installing #{@component_name} to #{@droplet.sandbox.relative_path_from(@droplet.root)}" do
52+
install_bin(@droplet.sandbox, file)
53+
end
54+
end
55+
@droplet.copy_resources
56+
end
57+
58+
# (see JavaBuildpack::Component::BaseComponent#release)
59+
def release
60+
@droplet
61+
.java_opts
62+
.add_system_property('java.io.tmpdir', '$TMPDIR')
63+
@droplet.java_opts << '-Xtune:virtualized'
64+
@droplet.java_opts.concat mem_opts
65+
@droplet.java_opts << '-Xshareclasses:none'
66+
end
67+
68+
private
69+
70+
# constant HEAP_RATIO is the ratio of memory assigned to the heap
71+
# as against the container total and is set using -Xmx.
72+
HEAP_RATIO = 0.75
73+
74+
KILO = 1024
75+
76+
private_constant :HEAP_RATIO, :KILO
77+
78+
# Installs the Downloaded InstallAnywhere (tm) BIN file to the target directory
79+
#
80+
# @param [String] target_directory, Where the java needs to be installed
81+
# @param [File] file, InstallAnywhere (tm) BIN file
82+
# @return [Void]
83+
def install_bin(target_directory, file)
84+
FileUtils.mkdir_p target_directory
85+
response_file = Tempfile.new('response.properties')
86+
response_file.puts('INSTALLER_UI=silent')
87+
response_file.puts('LICENSE_ACCEPTED=TRUE')
88+
response_file.puts("USER_INSTALL_DIR=#{target_directory}")
89+
response_file.close
90+
91+
File.chmod(0o755, file.path) unless File.executable?(file.path)
92+
shell "#{file.path} -i silent -f #{response_file.path} 2>&1"
93+
end
94+
95+
# Returns the max heap size ('-Xmx') value
96+
def mem_opts
97+
mopts = []
98+
total_memory = memory_limit_finder
99+
if total_memory.nil?
100+
# if no memory option has been set by cloudfoundry, we just assume defaults
101+
else
102+
calculated_heap_ratio = heap_ratio_verification(heap_ratio)
103+
heap_size = heap_size_calculator(total_memory, calculated_heap_ratio)
104+
mopts.push "-Xmx#{heap_size}"
105+
end
106+
mopts
107+
end
108+
109+
# Returns the heap_ratio attribute in config file (if specified) or the HEAP_RATIO constant value
110+
def heap_ratio
111+
@configuration['heap_ratio'] || HEAP_RATIO
112+
end
113+
114+
# Returns the container total memory limit in bytes
115+
def memory_limit_finder
116+
memory_limit = ENV['MEMORY_LIMIT']
117+
return nil unless memory_limit
118+
memory_limit_size = memory_size_bytes(memory_limit)
119+
raise "Invalid negative $MEMORY_LIMIT #{memory_limit}" if memory_limit_size < 0
120+
memory_limit_size
121+
end
122+
123+
# Returns the no. of bytes for a given string of minified size representation
124+
#
125+
# @param [String] size, A minified memory representation string
126+
# @return [Integer] bytes, value of size in bytes
127+
def memory_size_bytes(size)
128+
if size == '0'
129+
bytes = 0
130+
else
131+
raise "Invalid memory size '#{size}'" if !size || size.length < 2
132+
unit = size[-1]
133+
value = size[0..-2]
134+
raise "Invalid memory size '#{size}'" unless check_is_integer? value
135+
value = size.to_i
136+
# store the bytes
137+
bytes = calculate_bytes(unit, value)
138+
end
139+
bytes
140+
end
141+
142+
# Returns the no. of bytes for a given memory size unit
143+
#
144+
# @param [String] unit, Represents a Memory Size Unit
145+
# @param [Integer] value
146+
# @return [Integer] bytes, value of size in bytes
147+
def calculate_bytes(unit, value)
148+
if %w[b B].include?(unit)
149+
bytes = value
150+
elsif %w[k K].include?(unit)
151+
bytes = KILO * value
152+
elsif %w[m M].include?(unit)
153+
bytes = KILO * KILO * value
154+
elsif %w[g G].include?(unit)
155+
bytes = KILO * KILO * KILO * value
156+
else
157+
raise "Invalid unit '#{unit}' in memory size"
158+
end
159+
bytes
160+
end
161+
162+
# Checks whether the given value is an Integer
163+
#
164+
# @param [String] v, value as a string
165+
def check_is_integer?(v)
166+
v = Float(v)
167+
v && v.floor == v
168+
end
169+
170+
# Calculates the Heap size as per the Heap ratio
171+
#
172+
# @param [Integer] membytes, total memory in bytes
173+
# @param [Numeric] heapratio, Desired/Default Heap Ratio
174+
def heap_size_calculator(membytes, heapratio)
175+
memory_size_minified(membytes * heapratio)
176+
end
177+
178+
# Calculates the Memory Size in a Minified String Representation
179+
#
180+
# @param [Numeric] membytes, calculated heap size
181+
def memory_size_minified(membytes)
182+
giga = membytes / 2**(10 * 3)
183+
mega = membytes / 2**(10 * 2)
184+
kilo = (membytes / 2**(10 * 1)).round
185+
if check_is_integer?(giga)
186+
minified_size_calculator(giga, 'G')
187+
elsif check_is_integer?(mega)
188+
minified_size_calculator(mega, 'M')
189+
elsif check_is_integer?(kilo)
190+
minified_size_calculator(kilo, 'K')
191+
end
192+
end
193+
194+
# Returns the minified memory string
195+
#
196+
# @param [Integer] order, calculated memory value
197+
# @param [String] char, calculated memory unit
198+
# @return [String] minified memory string
199+
def minified_size_calculator(order, char)
200+
order.to_i.to_s + char
201+
end
202+
203+
# Verifies whether heap ratio is valid
204+
def heap_ratio_verification(ratio)
205+
raise 'Invalid heap ratio' unless ratio.is_a? Numeric
206+
raise 'heap ratio cannot be greater than 100%' unless ratio <= 1
207+
ratio
208+
end
209+
210+
end
211+
212+
end
213+
end

spec/fixtures/stub-download.bin

Whitespace-only changes.

spec/fixtures/stub-java.bin

Whitespace-only changes.

0 commit comments

Comments
 (0)