Scala sbt -D environemt variable not found - scala

I am trying to access an environment variable in my sbt build file.
As told I set the environment variable with the jvm -D Option
sbt -DaccessToken=***** compile
but scala cannot find the variable
sys.env.get("accessToken").getOrElse(throw new RuntimeException("System variable 'accessToken' with the credentials is not set."))
Why does the -D option have no effect?
If I set the variable with export in linux everything works fine.

Anything you pass as -D is not environment variable and cannot be read as sys.env.get.
You need to use Java API to read them
System.getProperty("accessToken")
Other option is to assign an environment variable before you launch your sbt. In bash, for example, it can be done like this but this, of course, depends on your environment.
accessToken=***** sbt compile

Related

Configuring SBT global settings

I need to permanently turn on the -verbose setting for SBT, without having to type it each time. What's the best way to do this? Putting -verbose in $SBT_OPTS does not have an effect.
-verbose flag can be enabled system-wide by saving it in global sbtopts configuration file. For example, on my machine, it is located at
/usr/local/etc/sbtopts
Here is an example of its contents
# set memory options
-mem 2048
# java version (default: java from PATH, currently $(java -version |& grep version))
-java-home /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
-verbose
Addressing the comment regarding IntelliJ, note that IntelliJ Scala Plugin currently does not read global sbtopts, however it does have support for local .sbtopts configuration file, but it does not support every option provided by sbt launcher script proper:
Supported options:
-no-share, -no-global, -sbt-boot, -sbt-dir, -ivy, -jvm-debug,
all options with -D and -J prefixes
Unsupported options:
-S prefix seems to be unsupported by sbt-launcher itself
-mem has a bit untrivial algorithm, same thing can be achieved
by configuring -Xmx, -Xms, -XX:ReservedCodeCacheSize options
-sbt-version, -sbt-rc, -sbt-snapshot, -sbt-jar
and -java-home are overriden by IDEA options
Other options have no impact on project importing process
SbtOpts.scala should list all the supported options. One notable absence is support for -mem, which means if we put, say, -mem 4096 in .sbtopts, then IntelliJ will simply ignore it. Similarly, the flag -verbose will not be picked up by IntelliJ sbt runner.
Hence the key is to understand that sbt runner script proper is not the same as IntelliJ custom made sbt runner component.
if you use unix friendly environment, you can create an alias for sbt in your ~/.bash/profile for example
alias sbt=sbt -verbose

Where do SBT env variables come from?

I'm moving my first steps with Scala (2.12.7) and SBT (1.2.7).
At some point, I want to get secret value from the environment:
sys.env("SECRET_TOKEN")
The problem is that, in the sbt shell, SECRET_TOKEN is not defined, therefore the application crashes.
So:
$ export SECRET_TOKEN="xxx"
$ sbt
[... sbt loads]
sbt> run
[ crashes because of the env var not found ]
It's like the sbt shell would get only a subset of the current environment.
Am I missing something?
Thanks
sbt (script + launcher) just launches a fancy java process, which should inherit the environment variables from the parent process.
Given
$ export SECRET_TOKEN="xxx"
Both build.sbt and your application during run should have access to sys.env("SECRET_TOKEN").
In the comment section, Bruno suggested SECRET_TOKEN="xxx" sbt, which apparently worked, but I don't know how that's different from export.
In any case,
object Hello extends App {
println(sys.env("SECRET_TOKEN"))
}
works for me
sbt:hello> run
[info] Running Hello
xxx

Environment variable based runtime configuration with sbt native packager

I'm using the sbt native packager plugin to create a zip file of my application for deployment to elastic beanstalk. I would like to set environment variables in my beanstalk environment and have those be used to configure my application at runtime. I've attempted to reference the env variables in my Procfile like so:
web: ./bin/bridgeservice -Dhttp.port=$PORT
This does not work as $PORT is not interpolated by the start script generated by the packager.
I've also attempted to define the variables in my build.sbt like so:
import scala.util.Properties
javaOptions in Universal ++= Seq(
"-Dhttp.port=" + Properties.envOrElse("PORT", "9004"),
)
This also does not work as the packager expects the PORT env variable at the time of building the distributable zip and hardcodes the default value of 9004 in an application.ini file.
Is it possible to dynamically pass java options based on environment variables at application startup?
The settings in javaOptions in Universal are compiled into conf/application.ini file, but accordingly to sbt-native-packager docs application.ini currently does not support variable substitution:
The file will be installed to ${app_home}/conf/application.ini and
read from there by the startscript. You can use # for comments and new
lines as you like. This file currently doesn’t has any variable
substitution. We recommend using the build.sbt if you need any
information from your build.
So,the env var based runtime settings can be achieved in several ways:
Solution #1. Add extra definitions to generated start script
In build.sbt:
bashScriptExtraDefines += """addJava "-Dhttp.port=${PORT:-9004}""""
Check out Application and runtime configuration documentation for more info.
Solution #2: Set JAVA_OPTS env var in the target server
Just set JAVA_OPTS environment variable on the target server and make it available for the start script. This can be the easiest solution for environments like AWS ElasticBeanstalk where env vars can be set on the app's environment configuration page.
Not sure if this will help, but I had similar issue when building docker images of my multi module project.
I ended with this:
def sysPropOrDefault(propName: String, default: String): String = Option(System.getProperty(propName)).getOrElse(default)
val somePort = sysPropOrDefault("port", "9004")
and in the project definition:
lazy val someProject = project("some-project")
.enablePlugins(JavaServerAppPackaging)
.settings(
javaOptions in Universal ++= Seq(
s"-Dhttp.port=$somePort"
)
)
Adding javaOptions to project settings level was crucial in my case. And s before option is not a typo.
When running command from terminal I called:
sbt clean update -Dport=9005 docker:publishLocal

Gradle not able to install properly

I am trying to install the gradle 1.3 on window 7 machine and did the following steps
1.Downloaded the gradle-1.3.all.zip from http://www.gradle.org/ url
2.Extracted it to F:\localRepository\gradle-1.3
3.Set the environment variables
GRADLE_HOME=F:\localRepository\gradle-1.3
GRADLE_OPTS=F:\localRepository\gradle-1.3\bin
PATH = F:\localRepository\gradle-1.3\bin;F:\jdk1.7.0_21\bin
JAVA_HOME=F:\jdk1.7.0_21
JAVA_OPTS=F:\jdk1.7.0_21\bin
4.RUN gradle in CMD
5.getting
"Could not find or load main class F:\jdk1.7.0_21\bin"
Can anyone suggest me what I am missing here?
Those JAVA_OPTS look suspicious to me. What are you trying to achieve by setting them to that?
If you look at gradle.bat (in F:\localRepository\gradle-1.3\bin) you'll see this line which actually launches Java to run Gradle:
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.launcher.GradleMain %CMD_LINE_ARGS%
So as far as Java's concerned, your %JAVA_OPTS% looks like the name of the main class. Everything after that just gets parsed as parameters.
JAVA_OPTS is for the parameters you want to pass to the JVM.
Your GRADLE_OPTS also looks a bit unusual.
about the JAVA_OPTS and GRADLE_OPTS I'm citing from Gradle documentation:
JVM OPTIONS
JVM options for running Gradle can be set via environment variables. You can use GRADLE_OPTS >or JAVA_OPTS. Those variables can be used together. JAVA_OPTS is by convention an environment >variable shared by many Java applications. A typical use case would be to set the HTTP proxy >in JAVA_OPTS and the memory options in GRADLE_OPTS. Those variables can also be set at the >beginning of the gradle or gradlew script.
http://www.gradle.org/installation
But in general it's not suitable placeholder for bin folder. You better define your Path variable as:
Path=%JAVA_HOME%\bin;%GRADLE_HOME%\bin;
and remove or redefine your JAVA_OPTS or GRADLE_OPTS variables.

sbt: Unable to specify application configuration in mingw

I am trying to launch an application using sbt's application launcher.
This application is defined as:
#!/bin/sh
java -jar /home/salil.wadnerkar/.conscript/sbt-launch.jar #"/home/salil.wadnerkar/.conscript/n8han/conscript/cs/launchconfig" "$#"
However, when I launch it, it gives me this error:
$ ~/bin/cs n8han/giter8
Error during sbt execution: Could not find configuration file 'C:/MinGW/msys/1.0/home/salil.wadnerkar/.conscript/n8han/conscript/cs/launchconfig'. Searched:
file:/C:/MinGW/msys/1.0/home/salil.wadnerkar/
file:/C:/Users/salil.wadnerkar/
file:/C:/MinGW/msys/1.0/home/salil.wadnerkar/.conscript/
However, the file is present there. So, I think it's because of some quirk in the way sbt handles mingw file path.
Does anybody know how I can get it working?
In Cygwin I used
java -jar "`cygpath -m "$HOME/.conscript/sbt-launch.jar"`" "#file:///C:/Users/cvanvranken/.conscript/n8han/conscript/cs/launchconfig" "$#"
I expect you will be able to get yours to work with something similar, perhaps this:
java -jar /home/salil.wadnerkar/.conscript/sbt-launch.jar "#file:///C:/Users/salil.wadnerkar/.conscript/n8han/conscript/cs/launchconfig" "$#"
or
java -jar /home/salil.wadnerkar/.conscript/sbt-launch.jar "#file:///C:/MinGW/msys/1.0/home/salil.wadnerkar/.conscript/n8han/conscript/cs/launchconfig" "$#"
if those fail, you still definitely need to use the file:// protocol.
Also note the three directories it is searching in the error message
file:/C:/MinGW/msys/1.0/home/salil.wadnerkar/
file:/C:/Users/salil.wadnerkar/
file:/C:/MinGW/msys/1.0/home/salil.wadnerkar/.conscript/
no matter what you put in the launchconfig parameter, if it is not recognized then those directories are searched by default. So you could have gibberish in your parameter and still see the same exact error you are getting now.
you can set the launch config path relative to the .conscript folder -
java -jar /home/salil.wadnerkar/.conscript/sbt-launch.jar #n8han/conscript/cs/launchconfig "$#"