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