Skip to content

Commit 3d833c2

Browse files
committed
distZip-style applications
This change adds support for distZip-style applications[1]. This means applications that are packaged as a start script in bin/ and classpath JARs in lib/ can be run. This package can be created with the Gradle application plugin, but also by the sbt-native-package plugin. [1]: http://www.gradle.org/docs/current/userguide/application_plugin.html [#69255612]
1 parent 5fc79a0 commit 3d833c2

File tree

17 files changed

+277
-36
lines changed

17 files changed

+277
-36
lines changed

.idea/.rakeTasks

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi
3232
* [Design](docs/design.md)
3333
* [Security](docs/security.md)
3434
* Standard Containers
35+
* [Dist ZIP](docs/container-dist_zip.md)
3536
* [Groovy](docs/container-groovy.md) ([Configuration](docs/container-groovy.md#configuration))
3637
* [Java Main](docs/container-java_main.md) ([Configuration](docs/container-java_main.md#configuration))
3738
* [Play Framework](docs/container-play_framework.md)

config/components.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
# Configuration for components to use in the buildpack
1717
---
1818
containers:
19+
- "JavaBuildpack::Container::DistZip"
1920
- "JavaBuildpack::Container::Groovy"
2021
- "JavaBuildpack::Container::JavaMain"
2122
- "JavaBuildpack::Container::PlayFramework"

docs/container-dist_zip.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Dist Zip Container
2+
The Dist Zip Container allows applications packaged in [`distZip`-style][] to be run.
3+
4+
<table>
5+
<tr>
6+
<td><strong>Detection Criteria</strong></td>
7+
<td><ul>
8+
<li>A start script in the <tt>bin/</tt> subdirectory of the application directory or one of its immediate subdirectories (but not in both), and</li>
9+
<li>A JAR file in the <tt>lib/</tt> subdirectory of the application directory or one of its immediate subdirectories (but not in both), and</li>
10+
<li>Not a Play Framework application</li>
11+
</ul></td>
12+
</tr>
13+
<tr>
14+
<td><strong>Tags</strong></td>
15+
<td><tt>dist-zip</tt></td>
16+
</tr>
17+
</table>
18+
Tags are printed to standard output by the buildpack detect script
19+
20+
## Configuration
21+
The Dist Zip Container cannot be configured.
22+
23+
24+
[`distZip`-style]: http://www.gradle.org/docs/current/userguide/application_plugin.html

docs/container-play_framework.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ The Play Framework Container allows Play Framework applications to be run.
33

44
<table>
55
<tr>
6-
<td><strong>Detection Criteria</strong></td><td>The Play Framework start script and the Play Framework runtime JAR exist in the appropriate subdirectories of the application directory or one of its immediate subdirectories (but not in both)</td>
6+
<td><strong>Detection Criteria</strong></td>
7+
<td>The Play Framework start script and the Play Framework runtime JAR exist in the appropriate subdirectories of the application directory or one of its immediate subdirectories (but not in both)</td>
78
</tr>
89
<tr>
910
<td><strong>Tags</strong></td>
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Encoding: utf-8
2+
# Cloud Foundry Java Buildpack
3+
# Copyright 2013 the original author or authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
require 'java_buildpack/component/base_component'
18+
require 'java_buildpack/container'
19+
require 'java_buildpack/util/dash_case'
20+
require 'java_buildpack/util/find_single_directory'
21+
require 'java_buildpack/util/play/factory'
22+
require 'java_buildpack/util/qualify_path'
23+
require 'java_buildpack/util/start_script'
24+
25+
module JavaBuildpack
26+
module Container
27+
28+
# Encapsulates the detect, compile, and release functionality for +distZip+ style applications.
29+
class DistZip < JavaBuildpack::Component::BaseComponent
30+
include JavaBuildpack::Util
31+
32+
# Creates an instance
33+
#
34+
# @param [Hash] context a collection of utilities used the component
35+
def initialize(context)
36+
super(context)
37+
end
38+
39+
# (see JavaBuildpack::Component::BaseComponent#detect)
40+
def detect
41+
supports? ? DistZip.to_s.dash_case : nil
42+
end
43+
44+
# (see JavaBuildpack::Component::BaseComponent#compile)
45+
def compile
46+
start_script.chmod 0755
47+
augment_classpath
48+
end
49+
50+
# (see JavaBuildpack::Component::BaseComponent#release)
51+
def release
52+
[
53+
@droplet.java_home.as_env_var,
54+
@droplet.java_opts.as_env_var,
55+
'SERVER_PORT=$PORT',
56+
qualify_path(start_script, @droplet.root)
57+
].flatten.compact.join(' ')
58+
end
59+
60+
private
61+
62+
PATTERN_APP_CLASSPATH = /^declare -r app_classpath=\"(.*)\"$/
63+
64+
PATTERN_CLASSPATH = /^CLASSPATH=(.*)$/.freeze
65+
66+
def augment_classpath
67+
content = start_script.read
68+
69+
if content =~ PATTERN_CLASSPATH
70+
additional_classpath = @droplet.additional_libraries.sort.map do |additional_library|
71+
"$APP_HOME/#{additional_library.relative_path_from(root)}"
72+
end
73+
74+
update_file start_script, content,
75+
PATTERN_CLASSPATH, "CLASSPATH=#{additional_classpath.join(':')}:\\1"
76+
elsif content =~ PATTERN_APP_CLASSPATH
77+
additional_classpath = @droplet.additional_libraries.sort.map do |additional_library|
78+
"$app_home/#{additional_library.relative_path_from(start_script.dirname)}"
79+
end
80+
81+
update_file start_script, content,
82+
PATTERN_APP_CLASSPATH, "declare -r app_classpath=\"#{additional_classpath.join(':')}:\\1\""
83+
end
84+
end
85+
86+
def jars?
87+
(lib_dir + '*.jar').glob.any?
88+
end
89+
90+
def lib_dir
91+
root + 'lib'
92+
end
93+
94+
def root
95+
find_single_directory || @droplet.root
96+
end
97+
98+
def start_script
99+
JavaBuildpack::Util.start_script root
100+
end
101+
102+
def supports?
103+
start_script && start_script.exist? && jars? && !JavaBuildpack::Util::Play::Factory.create(@droplet)
104+
end
105+
106+
def update_file(path, content, pattern, replacement)
107+
path.open('w') do |f|
108+
f.write content.gsub pattern, replacement
109+
f.fsync
110+
end
111+
end
112+
113+
end
114+
115+
end
116+
end

lib/java_buildpack/container/java_main.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ def release
4242
manifest_class_path.each { |path| @droplet.additional_libraries << path }
4343

4444
[
45+
port,
4546
"#{@droplet.java_home.root}/bin/java",
4647
@droplet.additional_libraries.as_classpath,
4748
@droplet.java_opts.join(' '),
4849
main_class,
49-
arguments,
50-
port
50+
arguments
5151
].flatten.compact.join(' ')
5252
end
5353

@@ -73,7 +73,7 @@ def manifest_class_path
7373
end
7474

7575
def port
76-
main_class =~ /^org\.springframework\.boot\.loader\.(?:[JW]ar|Properties)Launcher$/ ? '--server.port=$PORT' : nil
76+
main_class =~ /^org\.springframework\.boot\.loader\.(?:[JW]ar|Properties)Launcher$/ ? 'SERVER_PORT=$PORT' : nil
7777
end
7878

7979
end

lib/java_buildpack/container/spring_boot_cli.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,10 @@ def release
4949
[
5050
@droplet.java_home.as_env_var,
5151
@droplet.java_opts.as_env_var,
52+
'SERVER_PORT=$PORT',
5253
qualify_path(@droplet.sandbox + 'bin/spring', @droplet.root),
5354
'run',
54-
relative_groovy_files,
55-
'--',
56-
'--server.port=$PORT'
55+
relative_groovy_files
5756
].flatten.compact.join(' ')
5857
end
5958

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Encoding: utf-8
2+
# Cloud Foundry Java Buildpack
3+
# Copyright 2013 the original author or authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
require 'java_buildpack/util'
18+
19+
module JavaBuildpack
20+
module Util
21+
22+
# Find the single directory in the root of the droplet
23+
#
24+
# @return [Pathname, nil] the single directory in the root of the droplet, otherwise +nil+
25+
def find_single_directory
26+
roots = (@droplet.root + '*').glob.select { |child| child.directory? }
27+
roots.size == 1 ? roots.first : nil
28+
end
29+
30+
module_function :find_single_directory
31+
32+
end
33+
end

lib/java_buildpack/util/play/base.rb

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

1717
require 'java_buildpack/util/play'
18+
require 'java_buildpack/util/find_single_directory'
1819
require 'java_buildpack/util/qualify_path'
1920

2021
module JavaBuildpack
@@ -80,14 +81,6 @@ def augment_classpath
8081
fail "Method 'augment_classpath' must be defined"
8182
end
8283

83-
# Find the single directory in the root of the droplet
84-
#
85-
# @return [Pathname, nil] the single directory in the root of the droplet, otherwise +nil+
86-
def find_single_directory
87-
roots = (@droplet.root + '*').glob.select { |child| child.directory? }
88-
roots.size == 1 ? roots.first : nil
89-
end
90-
9184
# Returns the +JAVA_OPTS+ in the form that they need to be added to the command line
9285
#
9386
# @return [Array<String>] the +JAVA_OPTS+ in the form that they need to be added to the command line

0 commit comments

Comments
 (0)