Skip to content

Commit 62362c2

Browse files
committed
FIX #82 adding the ability to specify jvm options via sbt
1 parent d96a57d commit 62362c2

File tree

31 files changed

+379
-106
lines changed

31 files changed

+379
-106
lines changed

project/build.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
sbt.version=0.13.6
1+
sbt.version=0.13.8

project/plugins.sbt

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ resolvers += Resolver.url("sbt-plugin-releases", new URL("http://scalasbt.artifa
22

33
resolvers += "jgit-repo" at "http://download.eclipse.org/jgit/maven"
44

5-
addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.5.2")
5+
addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.5.3")
66

7-
addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "0.6.2")
7+
addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "0.8.0")
88

9-
addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "0.7.2")
9+
addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "0.8.1")
1010

1111
libraryDependencies <+= (sbtVersion) { sv =>
1212
"org.scala-sbt" % "scripted-plugin" % sv
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# #################################
2+
# ##### Default configuration #####
3+
# #################################
4+
5+
# Available replacements
6+
# ------------------------------------------------
7+
# ${{author}} debian author
8+
# ${{descr}} debian package description
9+
# ${{exec}} startup script name
10+
# ${{chdir}} app directory
11+
# ${{retries}} retries for startup
12+
# ${{retryTimeout}} retry timeout
13+
# ${{app_name}} normalized app name
14+
# ${{daemon_user}} daemon user
15+
# -------------------------------------------------
16+
17+
# DEPRECATED, use -J-Xmx1024m instead
18+
# -mem 1024
19+
20+
# Setting -X directly (-J is stripped)
21+
# -J-X
22+
# -J-Xmx1024
23+
24+
# Add additional jvm parameters
25+
# -Dkey=val
26+
27+
# For play applications you may set
28+
# -Dpidfile.path=/var/run/${{app_name}}/play.pid
29+
30+
# Turn on JVM debugging, open at the given port
31+
# -jvm-debug <port>
32+
33+
# Don't run the java version check
34+
# -no-version-check

src/main/resources/com/typesafe/sbt/packager/archetypes/bash-template

+2-31
Original file line numberDiff line numberDiff line change
@@ -150,34 +150,7 @@ addResidual () {
150150
addDebugger () {
151151
addJava "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$1"
152152
}
153-
# a ham-fisted attempt to move some memory settings in concert
154-
# so they need not be messed around with individually.
155-
get_mem_opts () {
156-
local mem=${1:-1024}
157-
local perm=$(( $mem / 4 ))
158-
(( $perm > 256 )) || perm=256
159-
(( $perm < 1024 )) || perm=1024
160-
local codecache=$(( $perm / 2 ))
161-
162-
# if we detect any of these settings in ${java_opts} we need to NOT output our settings.
163-
# The reason is the Xms/Xmx, if they don't line up, cause errors.
164-
if [[ "${java_opts}" == *-Xmx* ]] ||
165-
[[ "${java_opts}" == *-Xms* ]] ||
166-
[[ "${java_opts}" == *-XX:MaxPermSize* ]] ||
167-
[[ "${java_opts}" == *-XX:ReservedCodeCacheSize* ]] ||
168-
# check java arguments for settings, too
169-
[[ "${java_args[@]}" == *-Xmx* ]] ||
170-
[[ "${java_args[@]}" == *-Xms* ]] ||
171-
[[ "${java_args[@]}" == *-XX:MaxPermSize* ]] ||
172-
[[ "${java_args[@]}" == *-XX:ReservedCodeCacheSize* ]];
173-
then
174-
echo ""
175-
elif [[ !$no_version_check ]] && [[ "$java_version" > "1.8" ]]; then
176-
echo "-Xms${mem}m -Xmx${mem}m -XX:ReservedCodeCacheSize=${codecache}m"
177-
else
178-
echo "-Xms${mem}m -Xmx${mem}m -XX:MaxPermSize=${perm}m -XX:ReservedCodeCacheSize=${codecache}m"
179-
fi
180-
}
153+
181154
require_arg () {
182155
local type="$1"
183156
local opt="$2"
@@ -214,7 +187,7 @@ process_args () {
214187

215188
-no-version-check) no_version_check=1 && shift ;;
216189

217-
-mem) require_arg integer "$1" "$2" && app_mem="$2" && shift 2 ;;
190+
-mem) echo "!! WARNING !! -mem option is ignored. Please use -J-Xmx and -J-Xms" && shift 2 ;;
218191
-jvm-debug) require_arg port "$1" "$2" && addDebugger $2 && shift 2 ;;
219192

220193
-main) custom_mainclass="$2" && shift 2 ;;
@@ -274,7 +247,6 @@ run() {
274247

275248
# run sbt
276249
execRunner "$java_cmd" \
277-
$(get_mem_opts $app_mem) \
278250
${java_opts[@]} \
279251
"${java_args[@]}" \
280252
-cp "$(fix_classpath "$app_classpath")" \
@@ -328,7 +300,6 @@ Usage: $script_name [options]
328300
-v | -verbose this runner is chattier
329301
-d | -debug set sbt log level to debug
330302
-no-version-check Don't run the java version check.
331-
-mem <integer> set memory options in MB (default: $sbt_mem, which is $(get_mem_opts $sbt_mem))
332303
-main <classname> Define a custom main class
333304
-jvm-debug <port> Turn on JVM debugging, open at the given port.
334305
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
# #################################
2-
# ##### Default configuration #####
3-
# #################################
1+
# #####################################
2+
# ##### Environment Configuration #####
3+
# #####################################
4+
5+
# This file gets sourced before the actual bashscript
6+
# gets executed. You can use this file to provide
7+
# environment variables
48

59
# Available replacements
610
# ------------------------------------------------
@@ -14,21 +18,11 @@
1418
# ${{daemon_user}} daemon user
1519
# -------------------------------------------------
1620

17-
# Setting -Xmx and -Xms in Megabyte
18-
# -mem 1024
19-
20-
# Setting -X directly (-J is stripped)
21-
# -J-X
22-
# -J-Xmx1024
23-
24-
# Add additional jvm parameters
25-
# -Dkey=val
26-
27-
# For play applications you may set
28-
# -Dpidfile.path=/var/run/${{app_name}}/play.pid
29-
30-
# Turn on JVM debugging, open at the given port
31-
# -jvm-debug <port>
21+
# Setting JAVA_OPTS
22+
# -----------------
23+
# JAVA_OPTS="-Dpidfile.path=/var/run/${{app_name}}/play.pid $JAVA_OPTS"
3224

33-
# Don't run the java version check
34-
# -no-version-check
25+
# export env vars for 3rd party libs
26+
# ----------------------------------
27+
# COMPANY_API_KEY=123abc
28+
# export COMPANY_API_KEY

src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/systemloader/systemv/start-debian-template

+5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
source /lib/init/vars.sh
1313
source /lib/lsb/init-functions
1414

15+
# adding bashScriptEnvConfigLocation
16+
[[ -f ${{env_config}} ]] && . ${{env_config}}
17+
18+
# $JAVA_OPTS used in $RUN_CMD wrapper
19+
export JAVA_OPTS
1520

1621
PIDFILE=/var/run/${{app_name}}/running.pid
1722

src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/systemloader/systemv/start-rpm-template

+6
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@
2828
# Source function library.
2929
. /etc/rc.d/init.d/functions
3030

31+
# adding bashScriptEnvConfigLocation
32+
[[ -f ${{env_config}} ]] && . ${{env_config}}
33+
34+
# $JAVA_OPTS used in $RUN_CMD wrapper
35+
export JAVA_OPTS
36+
3137
prog="${{exec}}"
3238

3339
# FIXME The pid file should be handled by the executed script

src/main/scala/com/typesafe/sbt/packager/archetypes/JavaApp.scala

+49-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package packager
33
package archetypes
44

55
import sbt._
6-
import sbt.Keys.{ mappings, target, name, mainClass, sourceDirectory }
6+
import sbt.Keys.{ mappings, target, name, mainClass, sourceDirectory, javaOptions, streams }
77
import packager.Keys.{ packageName, executableScriptName }
88
import linux.{ LinuxFileMetaData, LinuxPackageMapping }
99
import linux.LinuxPlugin.autoImport.{ linuxPackageMappings, defaultLinuxInstallLocation }
@@ -39,13 +39,19 @@ object JavaAppPackaging extends AutoPlugin with JavaAppStartScript {
3939
*/
4040
val batTemplate = "bat-template"
4141

42+
/**
43+
* Location for the application.ini file used by the bash script to load initialization parameters for jvm and app
44+
*/
45+
val appIniLocation = "${app_home}/../conf/application.ini"
46+
4247
object autoImport extends JavaAppKeys
4348

4449
import JavaAppPackaging.autoImport._
4550

4651
override def requires = debian.DebianPlugin && rpm.RpmPlugin && docker.DockerPlugin && windows.WindowsPlugin
4752

4853
override def projectSettings = Seq(
54+
javaOptions in Universal := Nil,
4955
// Here we record the classpath as it's added to the mappings separately, so
5056
// we can use its order to generate the bash/bat scripts.
5157
scriptClasspathOrdering := Nil,
@@ -61,11 +67,34 @@ object JavaAppPackaging extends AutoPlugin with JavaAppStartScript {
6167
mappings in Universal <++= scriptClasspathOrdering,
6268
scriptClasspath <<= scriptClasspathOrdering map makeRelativeClasspathNames,
6369
bashScriptExtraDefines := Nil,
64-
bashScriptConfigLocation <<= bashScriptConfigLocation ?? None,
70+
// Create a bashConfigLocation if options are set in build.sbt
71+
bashScriptConfigLocation <<= bashScriptConfigLocation ?? Some(appIniLocation),
6572
bashScriptEnvConfigLocation <<= bashScriptEnvConfigLocation ?? None,
66-
bashScriptExtraDefines <++= (bashScriptEnvConfigLocation in Universal) map { _.map { config =>
67-
"[[ -f '" + config +"' ]] && source " + config
68-
}.toSeq },
73+
mappings in Universal := {
74+
val log = streams.value.log
75+
val universalMappings = (mappings in Universal).value
76+
val dir = (target in Universal).value
77+
val options = (javaOptions in Universal).value
78+
79+
bashScriptConfigLocation.value.collect {
80+
case location if options.nonEmpty =>
81+
val configFile = dir / "tmp" / "conf" / "application.ini"
82+
IO.writeLines(configFile, "# options from build" +: options)
83+
val filteredMappings = universalMappings.filter {
84+
case (file, path) => path != appIniLocation
85+
}
86+
// Warn the user if he tries to specify options
87+
if (filteredMappings.size < universalMappings.size) {
88+
log.warn("--------!!! JVM Options are defined twice !!!-----------")
89+
log.warn("application.ini is already present in output package. Will be overriden by 'javaOptions in Universal'")
90+
}
91+
(configFile -> cleanApplicationIniPath(location)) +: filteredMappings
92+
93+
}.getOrElse(universalMappings)
94+
95+
},
96+
97+
// ---
6998
bashScriptDefines <<= (Keys.mainClass in (Compile, bashScriptDefines), scriptClasspath in bashScriptDefines, bashScriptExtraDefines, bashScriptConfigLocation) map { (mainClass, cp, extras, config) =>
7099
val hasMain =
71100
for {
@@ -123,7 +152,7 @@ object JavaAppPackaging extends AutoPlugin with JavaAppStartScript {
123152
artifactClassifier.filterNot(_.isEmpty).map("-" + _).getOrElse("") +
124153
".jar"
125154

126-
// Determines a nicer filename for an attributed jar file, using the
155+
// Determines a nicer filename for an attributed jar file, using the
127156
// ivy metadata if available.
128157
private def getJarFullFilename(dep: Attributed[File]): String = {
129158
val filename: Option[String] = for {
@@ -208,6 +237,20 @@ object JavaAppPackaging extends AutoPlugin with JavaAppStartScript {
208237
dep <- deps
209238
realDep <- findRealDep(dep, projectArts)
210239
} yield realDep.data -> ("lib/" + getJarFullFilename(realDep))
240+
241+
/**
242+
* Currently unused.
243+
* TODO figure out a proper way to ship default `application.ini` if necessary
244+
*/
245+
protected def applicationIniTemplateSource: java.net.URL = getClass.getResource("application.ini-template")
246+
247+
/**
248+
* @param path that could be relative to app_home
249+
* @return path relative to app_home
250+
*/
251+
private def cleanApplicationIniPath(path: String): String = {
252+
path.replaceFirst("\\$\\{app_home\\}/../", "")
253+
}
211254
}
212255

213256
/**
@@ -272,4 +315,3 @@ trait JavaAppStartScript {
272315
}
273316

274317
}
275-

src/main/scala/com/typesafe/sbt/packager/archetypes/JavaAppKeys.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ trait JavaAppKeys {
1212
val bashScriptDefines = TaskKey[Seq[String]]("bashScriptDefines", "A list of definitions that should be written to the bash file template.")
1313
val bashScriptExtraDefines = TaskKey[Seq[String]]("bashScriptExtraDefines", "A list of extra definitions that should be written to the bash file template.")
1414
val bashScriptConfigLocation = TaskKey[Option[String]]("bashScriptConfigLocation", "The location where the bash script will load default argument configuration from.")
15-
val bashScriptEnvConfigLocation = TaskKey[Option[String]]("bashScriptEnvConfigLocation", "The location of a bash script that will be sourced before running the app.")
15+
val bashScriptEnvConfigLocation = SettingKey[Option[String]]("bashScriptEnvConfigLocation", "The location of a bash script that will be sourced before running the app.")
1616
val batScriptExtraDefines = TaskKey[Seq[String]]("batScriptExtraDefines", "A list of extra definitions that should be written to the bat file template.")
1717
val scriptClasspathOrdering = TaskKey[Seq[(File, String)]]("scriptClasspathOrdering", "The order of the classpath used at runtime for the bat/bash scripts.")
1818
val projectDependencyArtifacts = TaskKey[Seq[Attributed[File]]]("projectDependencyArtifacts", "The set of exported artifacts from our dependent projects.")

0 commit comments

Comments
 (0)