Home | History | Annotate | Download | only in build
      1 // Copyright 2017 Google Inc. All rights reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 package build
     16 
     17 import (
     18 	"regexp"
     19 	"runtime"
     20 	"strings"
     21 	"sync"
     22 )
     23 
     24 const incompatibleJavacStr = "google"
     25 
     26 var javaVersionInfo = struct {
     27 	once      sync.Once
     28 	startOnce sync.Once
     29 
     30 	java_version_output  string
     31 	javac_version_output string
     32 }{}
     33 
     34 func getJavaVersions(ctx Context, config Config) {
     35 	javaVersionInfo.startOnce.Do(func() {
     36 		go func() {
     37 			if ctx.Tracer != nil {
     38 				thread := ctx.Tracer.NewThread("java_version")
     39 				ctx.Tracer.Begin("get version", thread)
     40 				defer ctx.Tracer.End(thread)
     41 			}
     42 
     43 			getJavaVersionsImpl(ctx, config)
     44 		}()
     45 	})
     46 }
     47 
     48 func getJavaVersionsImpl(ctx Context, config Config) {
     49 	javaVersionInfo.once.Do(func() {
     50 		cmd := Command(ctx, config, "java", "java", "-version")
     51 		cmd.Environment.Unset("_JAVA_OPTIONS")
     52 		javaVersionInfo.java_version_output = string(cmd.CombinedOutputOrFatal())
     53 
     54 		cmd = Command(ctx, config, "javac", "javac", "-version")
     55 		cmd.Environment.Unset("_JAVA_OPTIONS")
     56 		javaVersionInfo.javac_version_output = string(cmd.CombinedOutputOrFatal())
     57 	})
     58 }
     59 
     60 func checkJavaVersion(ctx Context, config Config) {
     61 	ctx.BeginTrace("java_version_check")
     62 	defer ctx.EndTrace()
     63 
     64 	getJavaVersionsImpl(ctx, config)
     65 
     66 	var required_java_version string
     67 	var java_version_regexp *regexp.Regexp
     68 	var javac_version_regexp *regexp.Regexp
     69 
     70 	oj9_env, _ := config.Environment().Get("EXPERIMENTAL_USE_OPENJDK9")
     71 	experimental_use_openjdk9 := oj9_env != ""
     72 
     73 	if experimental_use_openjdk9 {
     74 		required_java_version = "9"
     75 		java_version_regexp = regexp.MustCompile(`^java .* "9.*"`)
     76 		javac_version_regexp = regexp.MustCompile(`^javac 9`)
     77 	} else {
     78 		required_java_version = "1.8"
     79 		java_version_regexp = regexp.MustCompile(`[ "]1\.8[\. "$]`)
     80 		javac_version_regexp = java_version_regexp
     81 	}
     82 
     83 	java_version := javaVersionInfo.java_version_output
     84 	javac_version := javaVersionInfo.javac_version_output
     85 
     86 	found := false
     87 	for _, l := range strings.Split(java_version, "\n") {
     88 		if java_version_regexp.MatchString(l) {
     89 			java_version = l
     90 			found = true
     91 			break
     92 		}
     93 	}
     94 	if !found {
     95 		ctx.Println("***************************************************************")
     96 		ctx.Println("You are attempting to build with the incorrect version of java.")
     97 		ctx.Println()
     98 		ctx.Println("Your version is:", java_version)
     99 		ctx.Println("The required version is:", required_java_version+".x")
    100 		ctx.Println()
    101 		ctx.Println("Please follow the machine setup instructions at:")
    102 		ctx.Println("    https://source.android.com/source/initializing.html")
    103 		ctx.Println("***************************************************************")
    104 		ctx.Fatalln("stop")
    105 	}
    106 
    107 	if runtime.GOOS == "linux" {
    108 		// Early access builds of OpenJDK 9 do not contain the string "openjdk" in the
    109 		// version name. TODO(tobiast): Reconsider once the OpenJDK 9 toolchain is stable.
    110 		// http://b/62123342
    111 		if !strings.Contains(java_version, "openjdk") && !experimental_use_openjdk9 {
    112 			ctx.Println("*******************************************************")
    113 			ctx.Println("You are attempting to build with an unsupported JDK.")
    114 			ctx.Println()
    115 			ctx.Println("Only an OpenJDK based JDK is supported.")
    116 			ctx.Println()
    117 			ctx.Println("Please follow the machine setup instructions at:")
    118 			ctx.Println("    https://source.android.com/source/initializing.html")
    119 			ctx.Println("*******************************************************")
    120 			ctx.Fatalln("stop")
    121 		}
    122 	} else { // darwin
    123 		if strings.Contains(java_version, "openjdk") {
    124 			ctx.Println("*******************************************************")
    125 			ctx.Println("You are attempting to build with an unsupported JDK.")
    126 			ctx.Println()
    127 			ctx.Println("You use OpenJDK, but only Sun/Oracle JDK is supported.")
    128 			ctx.Println()
    129 			ctx.Println("Please follow the machine setup instructions at:")
    130 			ctx.Println("    https://source.android.com/source/initializing.html")
    131 			ctx.Println("*******************************************************")
    132 			ctx.Fatalln("stop")
    133 		}
    134 	}
    135 
    136 	incompatible_javac := strings.Contains(javac_version, incompatibleJavacStr)
    137 
    138 	found = false
    139 	for _, l := range strings.Split(javac_version, "\n") {
    140 		if javac_version_regexp.MatchString(l) {
    141 			javac_version = l
    142 			found = true
    143 			break
    144 		}
    145 	}
    146 	if !found || incompatible_javac {
    147 		ctx.Println("****************************************************************")
    148 		ctx.Println("You are attempting to build with the incorrect version of javac.")
    149 		ctx.Println()
    150 		ctx.Println("Your version is:", javac_version)
    151 		if incompatible_javac {
    152 			ctx.Println("The '" + incompatibleJavacStr + "' version is not supported for Android platform builds.")
    153 			ctx.Println("Use a publically available JDK and make sure you have run envsetup.sh / lunch.")
    154 		} else {
    155 			ctx.Println("The required version is:", required_java_version)
    156 		}
    157 		ctx.Println()
    158 		ctx.Println("Please follow the machine setup instructions at:")
    159 		ctx.Println("    https://source.android.com/source/initializing.html")
    160 		ctx.Println("****************************************************************")
    161 		ctx.Fatalln("stop")
    162 	}
    163 }
    164