aboutsummaryrefslogtreecommitdiffstats
path: root/ui/build/java.go
blob: 5a09b1a2975419512ae5049b67192ed68fee7241 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package build

import (
	"regexp"
	"runtime"
	"strings"
	"sync"
)

const incompatibleJavacStr = "google"

var javaVersionInfo = struct {
	once      sync.Once
	startOnce sync.Once

	java_version_output  string
	javac_version_output string
}{}

func getJavaVersions(ctx Context, config Config) {
	javaVersionInfo.startOnce.Do(func() {
		go func() {
			if ctx.Tracer != nil {
				thread := ctx.Tracer.NewThread("java_version")
				ctx.Tracer.Begin("get version", thread)
				defer ctx.Tracer.End(thread)
			}

			getJavaVersionsImpl(ctx, config)
		}()
	})
}

func getJavaVersionsImpl(ctx Context, config Config) {
	javaVersionInfo.once.Do(func() {
		cmd := Command(ctx, config, "java", "java", "-version")
		cmd.Environment.Unset("_JAVA_OPTIONS")
		javaVersionInfo.java_version_output = string(cmd.CombinedOutputOrFatal())

		cmd = Command(ctx, config, "javac", "javac", "-version")
		cmd.Environment.Unset("_JAVA_OPTIONS")
		javaVersionInfo.javac_version_output = string(cmd.CombinedOutputOrFatal())
	})
}

func checkJavaVersion(ctx Context, config Config) {
	ctx.BeginTrace("java_version_check")
	defer ctx.EndTrace()

	getJavaVersionsImpl(ctx, config)

	var required_java_version string
	var java_version_regexp *regexp.Regexp
	var javac_version_regexp *regexp.Regexp
	if legacy, _ := config.Environment().Get("LEGACY_USE_JAVA7"); legacy != "" {
		required_java_version = "1.7"
		java_version_regexp = regexp.MustCompile(`^java .*[ "]1\.7[\. "$]`)
		javac_version_regexp = regexp.MustCompile(`[ "]1\.7[\. "$]`)
	} else {
		required_java_version = "1.8"
		java_version_regexp = regexp.MustCompile(`[ "]1\.8[\. "$]`)
		javac_version_regexp = java_version_regexp
	}

	java_version := javaVersionInfo.java_version_output
	javac_version := javaVersionInfo.javac_version_output

	found := false
	for _, l := range strings.Split(java_version, "\n") {
		if java_version_regexp.MatchString(l) {
			java_version = l
			found = true
			break
		}
	}
	if !found {
		ctx.Println("***************************************************************")
		ctx.Println("You are attempting to build with the incorrect version of java.")
		ctx.Println()
		ctx.Println("Your version is:", java_version)
		ctx.Println("The required version is:", required_java_version+".x")
		ctx.Println()
		ctx.Println("Please follow the machine setup instructions at:")
		ctx.Println("    https://source.android.com/source/initializing.html")
		ctx.Println("***************************************************************")
		ctx.Fatalln("stop")
	}

	if runtime.GOOS == "linux" {
		if !strings.Contains(java_version, "openjdk") {
			ctx.Println("*******************************************************")
			ctx.Println("You are attempting to build with an unsupported JDK.")
			ctx.Println()
			ctx.Println("Only an OpenJDK based JDK is supported.")
			ctx.Println()
			ctx.Println("Please follow the machine setup instructions at:")
			ctx.Println("    https://source.android.com/source/initializing.html")
			ctx.Println("*******************************************************")
			ctx.Fatalln("stop")
		}
	} else { // darwin
		if strings.Contains(java_version, "openjdk") {
			ctx.Println("*******************************************************")
			ctx.Println("You are attempting to build with an unsupported JDK.")
			ctx.Println()
			ctx.Println("You use OpenJDK, but only Sun/Oracle JDK is supported.")
			ctx.Println()
			ctx.Println("Please follow the machine setup instructions at:")
			ctx.Println("    https://source.android.com/source/initializing.html")
			ctx.Println("*******************************************************")
			ctx.Fatalln("stop")
		}
	}

	incompatible_javac := strings.Contains(javac_version, incompatibleJavacStr)

	found = false
	for _, l := range strings.Split(javac_version, "\n") {
		if javac_version_regexp.MatchString(l) {
			javac_version = l
			found = true
			break
		}
	}
	if !found || incompatible_javac {
		ctx.Println("****************************************************************")
		ctx.Println("You are attempting to build with the incorrect version of javac.")
		ctx.Println()
		ctx.Println("Your version is:", javac_version)
		if incompatible_javac {
			ctx.Println("The '" + incompatibleJavacStr + "' version is not supported for Android platform builds.")
			ctx.Println("Use a publically available JDK and make sure you have run envsetup.sh / lunch.")
		} else {
			ctx.Println("The required version is:", required_java_version)
		}
		ctx.Println()
		ctx.Println("Please follow the machine setup instructions at:")
		ctx.Println("    https://source.android.com/source/initializing.html")
		ctx.Println("****************************************************************")
		ctx.Fatalln("stop")
	}
}