Using specific JDK version for non Java build - travis-ci

Let's say I have a job using non JVM language. For the sake of this question let's assume that it is R so my .travis.yml looks like this:
language: r
Now, some of the packages I use interact with Java libraries and I'd like to fix JDK version (specifically to OpenJDK 8 if that matters).
Java projects have some tools like
jdk_switcher use openjdk8
but these don't seem to work if language is not set to Java.
Is there any clean built-in way to handle this?
I can imagine combining apt and script that updates-alternatives, but I'd like to avoid this path, unless it is necessary.

After installing openjdk8, I used update-alternatives (not sure if this is necessary) and then exported the JAVA_HOME and PATH environment variables. The relevant lines from my .travis.yml look something like:
before install:
- sudo apt install -y openjdk-8-jdk
- sudo update-alternatives --set java /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java
script:
- export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
- export PATH=$JAVA_HOME/bin:$PATH
- java -version
- R CMD javareconf
- R CMD build
- R CMD check

Related

Can't figure out how to use newer version of g++ in Centos 6 Docker image

I have a Docker image that is used for running tests in Jenkins and Bamboo. I need to upgrade the version of g++ used (to something with C++11 support).
I tried using a Dockerfile that looks roughly like the following one:
FROM docker.blahblahblah/centos/6.6:latest
RUN yum install -y git gcc-c++ imake centos-release-scl-rh devtoolset-7-toolchain
# I've tried putting this into /etc/bashrc, ~/.bashrc, ~/.bash_profile
RUN echo "source scl_source enable devtoolset-7" >> ~/.bashrc
My issue is that when g++ is used within the container, it uses the older one, instead of the newer one in devtoolset-7, even though the newer one should be sourced from the bashrc. (Maybe I'm misunderstanding how Docker will try to run everything.)
Could anyone point me in the right direction here?

envsubst command getting stuck in a container

I have a requirement that before an application runs, some part of it needs to read the environmental variable. For this I have the following docker file
FROM nodesource/jessie:0.12.7
# install gettext for envsubst
RUN apt-get update
RUN apt-get install -y gettext-base
# cache package.json and node_modules to speed up builds
ADD package.json package.json
RUN npm install
# Add source files
ADD src src
# Substiture value for backend endpoint env var
RUN envsubst < src/js/envapp.js > src/js/app.js
ADD node_modules node_modules
EXPOSE 8000
CMD ["npm","start"]
The above envsubst line reads (should read) an env variable $MYENV and substitutes it. But when I open the file app.js, its empty.
I checked if the environmental variable exists in the container and it does. Any reason its value is not read and substituted?
I also tried the same command in teh container and it works. It only does not work when I run the image
This is likely because $MYENV is not available for envsubst when you run the image.
Each RUN command runs on its own shell.
From the Docker documentations:
RUN (the command is run in a shell - /bin/sh -c - shell form)
You need to source your profile as well, for example if the $MYENV environment variable is available in the .bashrc file, you can modify your Dockerfile like this:
RUN source ~/.bashrc && envsubst < src/js/envapp.js > src/js/app.js
I encountered the same issues, and after much research and fishing through the internet. I managed to find a few work arounds to this issue. Below I'll list them and identifiable risks at the time of this "Answer post"
Solutions:
1.) apt-get install -y gettext its a standard GNU package language library, one of these libraries that it includes is envsubst` and I can confirm that it works for docker UBUNTU:latest and it should work for every flavored version.
2.) npm install envsub dependent on the "use case" - this approach would be better supported by node based projects.
3.) enstub cli project lib in my opinion it seems a bit overkill to downloading a custom cli from a random stranger but, it's also another option.
Risk:
apt-get install -y gettext:
1.) gettext - this approach would NOT be ideal for VM's as with any package library, it requires maintenance and updates as time passes. However, this isn't necessary for docker because once an a container is initialized and up and running we can create a bashscript to add the package, substitute env vars and then remove the package.
2.) It's a bad idea for VM's because it can be used to execute arbitrary code
npm install ensub
1.) envsub - updating packages and this approach wouldn't be ideal if your dealing with a different stack and not using nodejs.
NOTE:
There's also a PHP version for those developing a PHP application and it seems to work PHP's cli if you need a custom environment.
Resources:
GetText package library info: https://www.gnu.org/software/gettext/
GetText Risk - https://ubuntu.com/security/notices/USN-3815-2
PHP-GetText - apt-get install -y php-gettext
Custom ensubst cli: https://github.com/a8m/envsubst
I suggest that since your are using Node, you use the npm envsub module.
This module is well tested and is developed with docker in mind.
It avoids the need for relying on other dependencies when you already have the full Node arsenal at your fingertips.
envsub is described as
envsub is envsubst for NodeJS
NodeJS global CLI module providing file-level environment variable substitution via Handlebars
I am the author of the package. I think you will enjoy it.
I had some issues with envsubst in Docker.
For some reasons envsubst doesn't work when I try to copy the output in the same file. For example, this is not working:
RUN envsubst < file.conf > file.conf
But when I when I tried to use a temp file the issue disappeared:
RUN envsubst < file.conf > file.conf.temp && cp -f file.conf.temp file.conf

Install python3-gi for Travis-CI and Python >= 3.3

What is the correct way to install python3-gi on Travis-CI using the .travis.yml file?
The past recommendation was to use Python 3.2 (Travis-ci & Gobject introspection), but I would prefer testing against more recent versions.
I did try a few sensible combinations of commands, but my knowledge of the Travis-CI environment is very basic:
This for example fails with and without using system_site_packages: true:
before_install:
- sudo apt-get install -qq python3-gi
virtualenv:
- system_site_packages: true
Two examples of repositories that have this working (as far as I can tell):
https://github.com/ignatenkobrain/gnome-news (CircleCI)
https://github.com/devassistant/devassistant (Travis-CI)
In order to use a newer version you would either have to build it or use a container system like docker.
gnome-news has an example of a pygobject project using circleci (which is another free alternative to travis-ci). They are using fedora rawhide in docker which has the latest versions of the entire gnome stack.

Travis: Is there a way to use env vars to install package versions programmatically on container-based infrastructure?

In the .travis.yml for one of my projects, I determine what packages to install based on environment variables that I also set in the .travis.yml file. It looks like this:
env:
- CABALVER=1.18 GHCVER=7.8.1
- CABALVER=1.18 GHCVER=7.8.2
...
before_install:
...
- travis_retry sudo apt-get install cabal-install-$CABALVER ghc-$GHCVER
...
That's under the legacy infrastructure. I would like to switch to the container-based infrastructure, which would mean replacing the before_install line with something like:
addons:
apt:
packages:
- cabal-install-$CABALVER
- ghc-$GHCVER
...except that won't work, because env vars aren't set until after Travis attempts to install the requested apt packages. So, if I try to use the above, I get an error about how I'm trying to install packages called cabal-install- and ghc- (with the ending hyphens, but minus the version suffixes), which of course don't exist.
Is there a way to accomplish what I want on the container-based infrastructure? I could try to install all the versions at once and use the env vars later to determine which one to use on a given job, but (even if I could prevent all hell from breaking loose as a result of having multiple GHCs and Cabals installed at once) it would be really slow to install all of them for every build job, and that would negate the purpose of switching to container-based infrastructure.

How do I make grails choose the right JDK?

I'm using Mac OSX 10.8.5 with Oracle's Java 1.7 installed in addition to the mac's 1.6.
I have my JAVA_HOME set and the JAVA_HOME/bin in the front of my path.
When I run a grails compile from the command line I can see it's choosing the Java 1.6 instead of 1.7. How do I make the grails command-line choose the JDK I want?
➤ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home
➤ echo $PATH
/Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/bin /usr/local/share/npm/bin /Users/kbrodhagen/bin /Users/kbrodhagen/.rvm/bin /usr/bin /bin /usr/sbin /sbin /usr/local/bin /opt/X11/bin /usr/local/git/bin
➤ set -x JAVA_OPTS "-showversion"
➤ grails compile
java version "1.6.0_51"
Java(TM) SE Runtime Environment (build 1.6.0_51-b11-457-11M4509)
Java HotSpot(TM) 64-Bit Server VM (build 20.51-b01-457, mixed mode)
Which shell are you using and exactly how did you set JAVA_HOME? Grails should respect your JAVA_HOME setting as long as it is visible to the grails command, for example in bash you must export the variable rather than just setting it, in tcsh you would use setenv rather than set.
$ export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home
You can also remove /Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/bin from your PATH as /usr/bin/java will automatically delegate to the appropriate java command for the current JAVA_HOME.
If you want to localise the Java version only to Grails the best way is to edit below file,
.gvm/bin/gvm-init.sh
You can set the JAVA_HOME in this file as below,
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home
I have Java 8 in my machine and here I am setting java 1.7 for grails ONLY.
For the new SDKman method you can export JAVA_HOME in [YOUR HOME]/.sdkman/candidates/grails/[concrete version or current]/bin/grails
I needed to be able to switch between a Java 7/Grails 2.4.4 project and a Java 8/Spring 4 project in Ubuntu 12.04 and certain things made this difficult:
I'd set Java 8 as the default version after installing it using sudo apt-get install oracle-java8-set-default, but that apparently creates /etc/profile.d/jdk.sh and /etc/profile.d/jdk.csh containing JAVA_HOME, JRE_HOME and other env vars that prevented me from swapping the JDK.
This kinda worked, but the above env vars clouded things too much.
In the end, I removed both of the above items from my environment and the files in /etc/profile.d and I now:
Change the JDK by running sudo update-java-alternatives -s java-8-oracle (or java-7-oracle) as mentioned in the webupd8 article;
Run gvm to set the current or default grails and other tools as required
Seems messier than it should be, but I think it is working now.
If you use SDKMAN to install Grails (which is the currently recommended method), you can add any versions of Java you have installed to SDKMAN and it will manage them for you as well. For example:
sdk install java openjdk-8 /usr/lib/jvm/java-8-openjdk-amd64
sdk use java openjdk-8
Note that this will set JAVA_HOME for your user, so if you don't want that you may want to consider one of the other options.
$ echo $JAVA_HOME
/home/user/.sdkman/candidates/java/current
For more information: SDKMAN local versions

Resources