Skip to content

Commit 6d3933a

Browse files
committed
Java 9 Support
This change updates the buildpack for Java 9. This primarily involved dealing with the fact that security providers and extension directories are handled differently between Java 9 and all previous JREs. This change updates all users of these features to ensure that ext directories are not added and JARs that would be in those directories are added to the classpath in Java 9 and later. Note that this does not guarantee that all components will work in Java 9, just that the buildpack will build the proper environment to run an application. [cloudfoundry#495]
1 parent 96dac92 commit 6d3933a

15 files changed

Lines changed: 267 additions & 20 deletions

lib/java_buildpack/component/immutable_java_home.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ def java_8_or_later?
4848
@delegate.java_8_or_later?
4949
end
5050

51+
# Whether or not the version of Java is 9 or later
52+
#
53+
# @return [Boolean] +true+ iff the version is 9.0.0 or later
54+
def java_9_or_later?
55+
@delegate.java_9_or_later?
56+
end
57+
5158
# @return [Pathname] the root of the droplet's +JAVA_HOME+
5259
def root
5360
@delegate.root

lib/java_buildpack/component/mutable_java_home.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,17 @@ def java_8_or_later?
3939
@version >= VERSION_8
4040
end
4141

42+
# Whether or not the version of Java is 9 or later
43+
# @return [Boolean] +true+ if and only if the version is 9.0.0 or later
44+
def java_9_or_later?
45+
@version >= VERSION_9
46+
end
47+
4248
VERSION_8 = JavaBuildpack::Util::TokenizedVersion.new('1.8.0').freeze
4349

44-
private_constant :VERSION_8
50+
VERSION_9 = JavaBuildpack::Util::TokenizedVersion.new('9.0.0').freeze
51+
52+
private_constant :VERSION_8, :VERSION_9
4553

4654
end
4755

lib/java_buildpack/framework/container_security_provider.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,16 @@ class ContainerSecurityProvider < JavaBuildpack::Component::VersionedDependencyC
2626
def compile
2727
download_jar
2828
@droplet.security_providers.insert 1, 'org.cloudfoundry.security.CloudFoundryContainerProvider'
29+
@droplet.additional_libraries << (@droplet.sandbox + jar_name) if @droplet.java_home.java_9_or_later?
2930
end
3031

3132
# (see JavaBuildpack::Component::BaseComponent#release)
3233
def release
33-
@droplet.extension_directories << @droplet.sandbox
34+
if @droplet.java_home.java_9_or_later?
35+
@droplet.additional_libraries << (@droplet.sandbox + jar_name)
36+
else
37+
@droplet.extension_directories << @droplet.sandbox
38+
end
3439
end
3540

3641
protected

lib/java_buildpack/framework/dyadic_ekm_security_provider.rb

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,23 @@ def compile
3232

3333
@droplet.copy_resources
3434
@droplet.security_providers << 'com.dyadicsec.provider.DYCryptoProvider'
35+
@droplet.additional_libraries << dyadic_jar if @droplet.java_home.java_9_or_later?
3536

3637
credentials = @application.services.find_service(FILTER, 'ca', 'key', 'recv_timeout', 'retries', 'send_timeout',
3738
'servers')['credentials']
38-
write_key credentials['key']
39-
write_cert credentials['ca']
40-
write_conf credentials['servers'], credentials['send_timeout'], credentials['recv_timeout'],
41-
credentials['retries']
39+
write_files(credentials)
4240
end
4341

4442
# (see JavaBuildpack::Component::BaseComponent#release)
4543
def release
4644
@droplet.environment_variables
4745
.add_environment_variable 'LD_LIBRARY_PATH', @droplet.sandbox + 'usr/lib'
4846

49-
@droplet.extension_directories << ext_dir
47+
if @droplet.java_home.java_9_or_later?
48+
@droplet.additional_libraries << dyadic_jar
49+
else
50+
@droplet.extension_directories << ext_dir
51+
end
5052
end
5153

5254
protected
@@ -107,6 +109,13 @@ def write_conf(servers, send_timeout, recv_timeout, retries)
107109
end
108110
end
109111

112+
def write_files(credentials)
113+
write_key credentials['key']
114+
write_cert credentials['ca']
115+
write_conf credentials['servers'], credentials['send_timeout'], credentials['recv_timeout'],
116+
credentials['retries']
117+
end
118+
110119
def write_key(key)
111120
FileUtils.mkdir_p key_file.parent
112121
key_file.open(File::CREAT | File::WRONLY) do |f|

lib/java_buildpack/framework/luna_security_provider.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def compile
3232

3333
@droplet.copy_resources
3434
@droplet.security_providers << 'com.safenetinc.luna.provider.LunaProvider'
35+
@droplet.additional_libraries << luna_provider_jar if @droplet.java_home.java_9_or_later?
3536

3637
credentials = @application.services.find_service(FILTER, 'client', 'servers', 'groups')['credentials']
3738
write_client credentials['client']
@@ -42,7 +43,12 @@ def compile
4243
# (see JavaBuildpack::Component::BaseComponent#release)
4344
def release
4445
@droplet.environment_variables.add_environment_variable 'ChrystokiConfigurationPath', @droplet.sandbox
45-
@droplet.extension_directories << ext_dir
46+
47+
if @droplet.java_home.java_9_or_later?
48+
@droplet.additional_libraries << luna_provider_jar
49+
else
50+
@droplet.extension_directories << ext_dir
51+
end
4652
end
4753

4854
protected

lib/java_buildpack/framework/protect_app_security_provider.rb

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def compile
3333

3434
@droplet.copy_resources
3535
@droplet.security_providers << 'com.ingrian.security.nae.IngrianProvider'
36+
@droplet.additional_libraries << protect_app_jar if @droplet.java_home.java_9_or_later?
3637

3738
credentials = @application.services.find_service(FILTER, 'client', 'trusted_certificates')['credentials']
3839

@@ -44,7 +45,11 @@ def compile
4445

4546
# (see JavaBuildpack::Component::BaseComponent#release)
4647
def release
47-
@droplet.extension_directories << @droplet.sandbox + 'ext'
48+
if @droplet.java_home.java_9_or_later?
49+
@droplet.additional_libraries << protect_app_jar
50+
else
51+
@droplet.extension_directories << ext_dir
52+
end
4853

4954
credentials = @application.services.find_service(FILTER)['credentials']
5055
java_opts = @droplet.java_opts
@@ -55,9 +60,7 @@ def release
5560
.add_system_property('com.ingrian.security.nae.Key_Store_Location', keystore)
5661
.add_system_property('com.ingrian.security.nae.Key_Store_Password', password)
5762

58-
credentials
59-
.reject { |key, _| key =~ /^client$/ || key =~ /^trusted_certificates$/ }
60-
.each { |key, value| java_opts.add_system_property("com.ingrian.security.nae.#{key}", value) }
63+
add_additional_properties(credentials, java_opts)
6164
end
6265

6366
protected
@@ -73,6 +76,12 @@ def supports?
7376

7477
private_constant :FILTER
7578

79+
def add_additional_properties(credentials, java_opts)
80+
credentials
81+
.reject { |key, _| key =~ /^client$/ || key =~ /^trusted_certificates$/ }
82+
.each { |key, value| java_opts.add_system_property("com.ingrian.security.nae.#{key}", value) }
83+
end
84+
7685
def add_client_credentials(pkcs12)
7786
shell "#{keytool} -importkeystore -noprompt -destkeystore #{keystore} -deststorepass #{password} " \
7887
"-srckeystore #{pkcs12.path} -srcstorepass #{password} -srcstoretype pkcs12" \
@@ -88,6 +97,10 @@ def add_trusted_certificates(trusted_certificates)
8897
end
8998
end
9099

100+
def ext_dir
101+
@droplet.sandbox + 'ext'
102+
end
103+
91104
def keystore
92105
@droplet.sandbox + 'nae-keystore.jks'
93106
end
@@ -113,6 +126,10 @@ def password
113126
'nae-keystore-password'
114127
end
115128

129+
def protect_app_jar
130+
ext_dir + "IngrianNAE-#{@version}.000.jar"
131+
end
132+
116133
def write_certificate(certificate)
117134
Tempfile.open('certificate-') do |f|
118135
f.write "#{certificate}\n"

lib/java_buildpack/jre/open_jdk_like_security_providers.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,19 @@ def compile
3636

3737
# (see JavaBuildpack::Component::BaseComponent#release)
3838
def release
39+
return if @droplet.java_home.java_9_or_later?
3940
@droplet.extension_directories << java_security.parent.parent + 'ext' unless java_security.nil?
4041
end
4142

4243
private
4344

45+
JAVA_9_SECURITY = 'conf/security/java.security'.freeze
46+
4447
JRE_SECURITY = 'lib/security/java.security'.freeze
4548

4649
SERVER_JRE_SECURITY = 'jre/lib/security/java.security'.freeze
4750

48-
private_constant :JRE_SECURITY, :SERVER_JRE_SECURITY
51+
private_constant :JAVA_9_SECURITY, :JRE_SECURITY, :SERVER_JRE_SECURITY
4952

5053
def existing_security_providers(existing_security)
5154
JavaBuildpack::Util::Properties.new(existing_security)
@@ -59,11 +62,16 @@ def index(entry)
5962
end
6063

6164
def java_security
65+
return java_9_security if @droplet.java_home.java_9_or_later? && java_9_security.exist?
6266
return jre_security if jre_security.exist?
6367
return server_jre_security if server_jre_security.exist?
6468
nil
6569
end
6670

71+
def java_9_security
72+
@droplet.java_home.root + JAVA_9_SECURITY
73+
end
74+
6775
def jre_security
6876
@droplet.java_home.root + JRE_SECURITY
6977
end

spec/droplet_helper.rb

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@
2222
require 'java_buildpack/component/extension_directories'
2323
require 'java_buildpack/component/immutable_java_home'
2424
require 'java_buildpack/component/java_opts'
25+
require 'java_buildpack/component/mutable_java_home'
2526
require 'java_buildpack/component/networking'
2627
require 'java_buildpack/component/security_providers'
2728
require 'java_buildpack/util/snake_case'
29+
require 'java_buildpack/util/tokenized_version'
2830
require 'pathname'
2931

3032
shared_context 'droplet_helper' do
@@ -48,8 +50,15 @@
4850
let(:sandbox) { droplet.sandbox }
4951

5052
let(:java_home) do
51-
delegate = instance_double('MutableJavaHome', root: app_dir + '.test-java-home', version: %w[1 7 55 u60])
52-
JavaBuildpack::Component::ImmutableJavaHome.new delegate, app_dir
53+
JavaBuildpack::Component::ImmutableJavaHome.new java_home_delegate, app_dir
54+
end
55+
56+
let(:java_home_delegate) do
57+
delegate = JavaBuildpack::Component::MutableJavaHome.new
58+
delegate.root = app_dir + '.test-java-home'
59+
delegate.version = JavaBuildpack::Util::TokenizedVersion.new('1.7.0_55')
60+
61+
delegate
5362
end
5463

5564
let(:environment_variables) do

spec/java_buildpack/component/immutable_java_home_spec.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
instance_double(JavaBuildpack::Component::MutableJavaHome,
2525
root: Pathname.new('test-java-home'),
2626
java_8_or_later?: true,
27+
java_9_or_later?: true,
2728
version: JavaBuildpack::Util::TokenizedVersion.new('1.2.3_u04'))
2829
end
2930

@@ -45,4 +46,8 @@
4546
expect(immutable_java_home.java_8_or_later?).to be
4647
end
4748

49+
it 'returns the delegate Java 9 or later' do
50+
expect(immutable_java_home.java_9_or_later?).to be
51+
end
52+
4853
end

spec/java_buildpack/component/mutable_java_home_spec.rb

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,44 @@
3636
expect(mutable_java_home.version).to eq(java_version)
3737
end
3838

39-
it 'recognizes Java 6' do
39+
it 'recognizes Java 6 as earlier than Java 8' do
4040
mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.6.0')
4141
expect(mutable_java_home.java_8_or_later?).not_to be
4242
end
4343

44-
it 'recognizes Java 7' do
44+
it 'recognizes Java 7 as earlier than Java 8' do
4545
mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.7.0')
4646
expect(mutable_java_home.java_8_or_later?).not_to be
4747
end
4848

49-
it 'recognizes Java 8' do
49+
it 'recognizes Java 8 as later than or equal to Java 8' do
5050
mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.8.0')
5151
expect(mutable_java_home.java_8_or_later?).to be
5252
end
5353

54-
it 'recognizes Java 9' do
55-
mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.9.0')
54+
it 'recognizes Java 9 as later than or equal to Java 8' do
55+
mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('9.0.0')
5656
expect(mutable_java_home.java_8_or_later?).to be
5757
end
5858

59+
it 'recognizes Java 6 as earlier than Java 9' do
60+
mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.6.0')
61+
expect(mutable_java_home.java_9_or_later?).not_to be
62+
end
63+
64+
it 'recognizes Java 7 as earlier than Java 9' do
65+
mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.7.0')
66+
expect(mutable_java_home.java_9_or_later?).not_to be
67+
end
68+
69+
it 'recognizes Java 8 as earlier than Java 9' do
70+
mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.8.0')
71+
expect(mutable_java_home.java_9_or_later?).not_to be
72+
end
73+
74+
it 'recognizes Java 9 as later than or equal to Java 9' do
75+
mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('9.0.0')
76+
expect(mutable_java_home.java_9_or_later?).to be
77+
end
78+
5979
end

0 commit comments

Comments
 (0)