blob: 9e6c0717dd9e21dc537e541e786ccb394c2e82c9 [file] [log] [blame]
Laszlo Csomor68c86562016-09-19 12:59:16 +00001#!/bin/bash
2#
3# Copyright 2016 The Bazel Authors. All rights reserved.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17# These are end to end tests for building Java.
Luis Fernando Pino Duquefa389062016-10-18 14:28:42 +000018CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
19source "${CURRENT_DIR}/../shell_utils.sh" \
Laszlo Csomor68c86562016-09-19 12:59:16 +000020 || { echo "shell_utils.sh not found!" >&2; exit 1; }
21
Luis Fernando Pino Duquefa389062016-10-18 14:28:42 +000022# Load the test setup defined in the parent directory
23source "${CURRENT_DIR}/../integration_test_setup.sh" \
24 || { echo "integration_test_setup.sh not found!" >&2; exit 1; }
25
jcater137f9692019-08-12 02:31:34 -070026# Load the helper utils.
27source "${CURRENT_DIR}/java_integration_test_utils.sh" \
28 || { echo "java_integration_test_utils.sh not found!" >&2; exit 1; }
Laszlo Csomor68c86562016-09-19 12:59:16 +000029set -eu
30
31declare -r runfiles_relative_javabase="$1"
Luis Fernando Pino Duquefa389062016-10-18 14:28:42 +000032add_to_bazelrc "build --package_path=%workspace%"
Laszlo Csomor68c86562016-09-19 12:59:16 +000033
34#### HELPER FUNCTIONS ##################################################
35
36function setup_local_jdk() {
37 local -r dest="$1"
38 local -r src="${BAZEL_RUNFILES}/${runfiles_relative_javabase}"
39
40 mkdir -p "$dest" || fail "mkdir -p $dest"
41 cp -LR "${src}"/* "$dest" || fail "cp -LR \"${src}\"/* \"$dest\""
42 chmod -R ug+rwX "$dest" || fail "chmod -R ug+rwX \"$dest\""
43}
44
45function write_hello_world_files() {
46 local pkg="$1"
47 mkdir -p $pkg/java/hello || fail "mkdir"
48 cat >$pkg/java/hello/BUILD <<EOF
49java_binary(name = 'hello',
50 srcs = ['Hello.java'],
51 main_class = 'hello.Hello')
52EOF
53
54 cat >$pkg/java/hello/Hello.java <<EOF
55package hello;
56public class Hello {
57 public static void main(String[] args) {
58 System.out.println("Hello, World!");
59 }
60}
61EOF
62}
63
64function write_hello_world_files_for_singlejar() {
65 local -r pkg="$1"
66 mkdir -p $pkg/java/hello || fail "mkdir"
67 cat >$pkg/java/hello/BUILD <<EOF
68java_binary(name = 'hello',
69 srcs = ['Hello.java'],
70 main_class = 'hello.Hello')
71EOF
72
73 cat >$pkg/java/hello/Hello.java <<EOF
74package hello;
75import java.util.Properties;
76public class Hello {
77 private static void printMap(Properties p) {
78 System.err.println("Available keys and values are:");
79 for (Object key : p.keySet()) {
80 System.err.printf(" '%s': '%s'%n", key, p.get(key));
81 }
82 }
83
84 public static void main(String[] args) throws Exception {
85 Properties properties = new Properties();
86 properties.load(Hello.class.getResourceAsStream("/build-data.properties"));
87 for (String arg : args) {
88 String[] keyValue = arg.split("=", 2);
89 Object value = properties.get(keyValue[0]);
90 if (value == null) {
91 System.err.println("Key '" + keyValue[0] + "' not found");
92 printMap(properties);
93 return;
94 }
95 if (keyValue.length > 1 && !keyValue[1].equals(value)) {
96 System.err.println("Value for key '" + keyValue[0] + "' is '" + value
97 + "' while it should be '" + keyValue[1] + "'");
98 printMap(properties);
99 return;
100 }
101 }
102 System.out.println("Hello, World!");
103 }
104}
105EOF
106}
107
108function write_hello_library_files() {
109 local -r pkg="$1"
110 mkdir -p $pkg/java/main || fail "mkdir"
111 cat >$pkg/java/main/BUILD <<EOF
112java_binary(
113 name = 'main',
114 deps = ['//$pkg/java/hello_library'],
115 srcs = ['Main.java'],
116 main_class = 'main.Main',
117 deploy_manifest_lines = ['k1: v1', 'k2: v2'])
118EOF
119
120 cat >$pkg/java/main/Main.java <<EOF
121package main;
122import hello_library.HelloLibrary;
123public class Main {
124 public static void main(String[] args) {
125 HelloLibrary.funcHelloLibrary();
126 System.out.println("Hello, World!");
127 }
128}
129EOF
130
131 mkdir -p $pkg/java/hello_library || fail "mkdir"
132 cat >$pkg/java/hello_library/BUILD <<EOF
133package(default_visibility=['//visibility:public'])
134java_library(name = 'hello_library',
135 srcs = ['HelloLibrary.java']);
136EOF
137
138 cat >$pkg/java/hello_library/HelloLibrary.java <<EOF
139package hello_library;
140public class HelloLibrary {
141 public static void funcHelloLibrary() {
142 System.out.print("Hello, Library!;");
143 }
144}
145EOF
146}
147
148function write_hello_sailor_files() {
149 local -r pkg="$1"
150 mkdir -p $pkg/java/hellosailor || fail "mkdir"
151 cat >$pkg/java/hellosailor/BUILD <<EOF
152java_binary(name = 'hellosailor',
153 srcs = ['HelloSailor.java'],
154 create_executable = 0)
155EOF
156
157 cat >$pkg/java/hellosailor/HelloSailor.java <<EOF
158package hellosailor;
159public class HelloSailor {
160 public static int addtwoNumbers(int a, int b) {
161 return a + b;
162 }
163}
164EOF
165}
166
167
168#### TESTS #############################################################
169
170# This test intentionally show some errors on the standard output.
171function test_compiles_hello_world() {
172 local -r pkg="${FUNCNAME[0]}"
173 mkdir "$pkg" || fail "mkdir $pkg"
174 write_hello_world_files "$pkg"
175
176 bazel clean
cushon998b4102019-04-01 08:59:07 -0700177 bazel build //$pkg/java/hello:hello || fail "build failed"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000178 ${PRODUCT_NAME}-bin/$pkg/java/hello/hello | grep -q 'Hello, World!' \
179 || fail "comparison failed"
180 function check_deploy_jar_should_not_exist() {
181 "$@" && fail "deploy jar should not exist"
182 true # reset the last exit code so the test won't be considered failed
183 }
184 function check_arglists() {
185 check_deploy_jar_should_not_exist "$@" --singlejar
186 check_deploy_jar_should_not_exist "$@" --wrapper_script_flag=--singlejar
187 check_deploy_jar_should_not_exist "$@" REGULAR_ARG \
188 --wrapper_script_flag=--singlejar
189 }
190 check_arglists bazel run //$pkg/java/hello:hello --
191 check_arglists ${PRODUCT_NAME}-bin/$pkg/java/hello/hello
192}
193
194function test_compiles_hello_world_from_deploy_jar() {
195 local -r pkg="${FUNCNAME[0]}"
196 mkdir "$pkg" || fail "mkdir $pkg"
197 write_hello_world_files "$pkg"
198
cushon998b4102019-04-01 08:59:07 -0700199 bazel build //$pkg/java/hello:hello_deploy.jar || fail "build failed"
Luis Fernando Pino Duquefa389062016-10-18 14:28:42 +0000200
cushon998b4102019-04-01 08:59:07 -0700201 bazel run //$pkg/java/hello:hello -- --singlejar | grep -q 'Hello, World!' \
Luis Fernando Pino Duquefa389062016-10-18 14:28:42 +0000202 || fail "comparison failed"
203 ${PRODUCT_NAME}-bin/$pkg/java/hello/hello -- --singlejar | \
204 grep -q 'Hello, World!' || fail "comparison failed"
205
cushon998b4102019-04-01 08:59:07 -0700206 bazel run //$pkg/java/hello:hello -- --wrapper_script_flag=--singlejar \
Luis Fernando Pino Duquefa389062016-10-18 14:28:42 +0000207 | grep -q 'Hello, World!' || fail "comparison failed"
208 ${PRODUCT_NAME}-bin/$pkg/java/hello/hello -- \
209 --wrapper_script_flag=--singlejar | grep -q 'Hello, World!' \
210 || fail "comparison failed"
211
cushon998b4102019-04-01 08:59:07 -0700212 bazel run //$pkg/java/hello:hello -- REGULAR_ARG \
Luis Fernando Pino Duquefa389062016-10-18 14:28:42 +0000213 --wrapper_script_flag=--singlejar | grep -q 'Hello, World!' \
214 || fail "comparison failed"
215 ${PRODUCT_NAME}-bin/$pkg/java/hello/hello -- REGULAR_ARG \
216 --wrapper_script_flag=--singlejar | grep -q 'Hello, World!' \
217 || fail "comparison failed"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000218}
219
220function test_explicit_bogus_wrapper_args_are_rejected() {
221 local -r pkg="${FUNCNAME[0]}"
222 mkdir "$pkg" || fail "mkdir $pkg"
223 write_hello_world_files "$pkg"
224
cushon998b4102019-04-01 08:59:07 -0700225 bazel build //$pkg/java/hello:hello_deploy.jar || fail "build failed"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000226 function check_arg_rejected() {
227 "$@" && fail "bogus arg should be rejected"
228 true # reset the last exit code so the test won't be considered failed
229 }
230 function check_arglists() {
231 check_arg_rejected "$@" --wrapper_script_flag=--bogus
232 check_arg_rejected "$@" REGULAR_ARG --wrapper_script_flag=--bogus
233 }
234 check_arglists bazel run //$pkg/java/hello:hello --
235 check_arglists ${PRODUCT_NAME}-bin/$pkg/java/hello/hello
236}
237
238function assert_singlejar_works() {
239 local -r pkg="$1"
240 local -r copy_jdk="$2"
241 local -r stamp_arg="$3"
242 local -r embed_label="$4"
243 local -r expected_build_data="$5"
244
245 write_hello_world_files_for_singlejar "$pkg"
246
247 if "$copy_jdk"; then
248 local -r local_jdk="$pkg/my_jdk"
249 setup_local_jdk "$local_jdk"
250
251 ln -s "my_jdk" "$pkg/my_jdk.symlink"
252 local -r javabase="$(get_real_path "$pkg/my_jdk.symlink")"
253 else
254 local -r javabase="${BAZEL_RUNFILES}/${runfiles_relative_javabase}"
255 fi
256
lberki2ea4fa22017-10-11 11:42:53 +0200257 mkdir -p "$pkg/jvm"
258 cat > "$pkg/jvm/BUILD" <<EOF
259package(default_visibility=["//visibility:public"])
cushon85da59f2019-04-03 11:41:01 -0700260java_runtime(
261 name='runtime',
262 java_home='$javabase',
263)
cushon37c85352019-04-10 16:17:23 -0700264EOF
jcater137f9692019-08-12 02:31:34 -0700265 create_java_test_platforms
lberki2ea4fa22017-10-11 11:42:53 +0200266
Laszlo Csomor68c86562016-09-19 12:59:16 +0000267 # Set javabase to an absolute path.
268 bazel build //$pkg/java/hello:hello //$pkg/java/hello:hello_deploy.jar \
Ivo Listf5b6abc2020-12-16 23:50:56 -0800269 "$stamp_arg" \
cushon85da59f2019-04-03 11:41:01 -0700270 --extra_toolchains="//$pkg/jvm:all,//tools/jdk:all" \
271 --platforms="//$pkg/jvm:platform" \
272 "$embed_label" >&"$TEST_log" \
Laszlo Csomor68c86562016-09-19 12:59:16 +0000273 || fail "Build failed"
274
275 mkdir $pkg/ugly/ || fail "mkdir failed"
276 # The stub script follows symlinks, so copy the files.
277 cp ${PRODUCT_NAME}-bin/$pkg/java/hello/hello $pkg/ugly/
278 cp ${PRODUCT_NAME}-bin/$pkg/java/hello/hello_deploy.jar $pkg/ugly/
Laszlo Csomor68c86562016-09-19 12:59:16 +0000279 $pkg/ugly/hello build.target build.time build.timestamp \
Androbin9c78a792017-11-29 01:31:47 -0800280 main.class=hello.Hello "$expected_build_data" >> $TEST_log 2>&1
Laszlo Csomor68c86562016-09-19 12:59:16 +0000281 expect_log 'Hello, World!'
282}
283
284function test_singlejar_with_default_jdk_with_stamp() {
285 local -r pkg="${FUNCNAME[0]}"
286 assert_singlejar_works "$pkg" true "--stamp" "--embed_label=toto" \
287 "build.label=toto"
288}
289
290# Regression test for b/17658100, ensure that --nostamp generate correct
291# build-info.properties file.
292function test_singlejar_with_default_jdk_without_stamp() {
293 local -r pkg="${FUNCNAME[0]}"
294 assert_singlejar_works "$pkg" true "--nostamp" "--embed_label=" \
295 "build.timestamp.as.int=0"
296}
297
298# Regression test for b/3244955, to ensure that running the deploy jar works
299# even without the runfiles available.
300function test_singlejar_with_custom_jdk_with_stamp() {
301 local -r pkg="${FUNCNAME[0]}"
302 assert_singlejar_works "$pkg" false "--stamp" "--embed_label=toto" \
303 "build.label=toto"
304}
305
306function test_singlejar_with_custom_jdk_without_stamp() {
307 local -r pkg="${FUNCNAME[0]}"
308 assert_singlejar_works "$pkg" false "--nostamp" "--embed_label=" \
309 "build.timestamp.as.int=0"
310}
311
312# Regression test for b/18191163: ensure that the build is deterministic when
313# used with --nostamp.
314function test_deterministic_nostamp_build() {
315 local -r pkg="${FUNCNAME[0]}"
316 mkdir "$pkg" || fail "mkdir $pkg"
317 write_hello_world_files "$pkg"
318
319 bazel clean || fail "Clean failed"
cushon998b4102019-04-01 08:59:07 -0700320 bazel build --nostamp //$pkg/java/hello:hello_deploy.jar \
Laszlo Csomor68c86562016-09-19 12:59:16 +0000321 || fail "Build failed"
Xin Gao33d05f62017-06-21 17:13:23 +0200322 # TODO(bazel-team) .a files (C/C++ static library file generated by
323 # archive tool) on darwin OS only are not deterministic.
324 # https://github.com/bazelbuild/bazel/issues/3156
Laszlo Csomor68c86562016-09-19 12:59:16 +0000325 local -r first_run="$(md5_file $(find "${PRODUCT_NAME}-out/" -type f '!' \
Xin Gao33d05f62017-06-21 17:13:23 +0200326 -name build-changelist.txt -a '!' -name volatile-status.txt \
Androbinef381e52017-12-14 07:24:27 -0800327 -a '!' -name 'stderr-*' -a '!' -name '*.a' \
Xin Gao33d05f62017-06-21 17:13:23 +0200328 -a '!' -name __xcodelocatorcache -a '!' -name __xcruncache \
329 | sort -u))"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000330
331 sleep 1 # Ensure the timestamp change between builds.
332
333 bazel clean || fail "Clean failed"
334 bazel build --nostamp //$pkg/java/hello:hello_deploy.jar \
335 || fail "Build failed"
336 local -r second_run="$(md5_file $(find "${PRODUCT_NAME}-out/" -type f '!' \
Xin Gao33d05f62017-06-21 17:13:23 +0200337 -name build-changelist.txt -a '!' -name volatile-status.txt \
Androbinef381e52017-12-14 07:24:27 -0800338 -a '!' -name 'stderr-*' -a '!' -name '*.a' \
Xin Gao33d05f62017-06-21 17:13:23 +0200339 -a '!' -name __xcodelocatorcache -a '!' -name __xcruncache \
340 | sort -u))"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000341
342 assert_equals "$first_run" "$second_run"
343}
344
345function test_compiles_hello_library() {
346 local -r pkg="${FUNCNAME[0]}"
347 mkdir "$pkg" || fail "mkdir $pkg"
348 write_hello_library_files "$pkg"
349
350 bazel clean
cushon998b4102019-04-01 08:59:07 -0700351 bazel build //$pkg/java/main:main || fail "build failed"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000352 ${PRODUCT_NAME}-bin/$pkg/java/main/main \
353 | grep -q "Hello, Library!;Hello, World!" || fail "comparison failed"
cushon998b4102019-04-01 08:59:07 -0700354 bazel run //$pkg/java/main:main -- --singlejar && fail "deploy jar should not exist"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000355
356 true # reset the last exit code so the test won't be considered failed
357}
358
359function test_compiles_hello_library_using_ijars() {
360 local -r pkg="${FUNCNAME[0]}"
361 mkdir "$pkg" || fail "mkdir $pkg"
362 write_hello_library_files "$pkg"
363
364 bazel clean
cushon998b4102019-04-01 08:59:07 -0700365 bazel build --use_ijars //$pkg/java/main:main || fail "build failed"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000366 ${PRODUCT_NAME}-bin/$pkg/java/main/main \
367 | grep -q "Hello, Library!;Hello, World!" || fail "comparison failed"
368}
369
370function test_compiles_hello_library_from_deploy_jar() {
371 local -r pkg="${FUNCNAME[0]}"
372 mkdir "$pkg" || fail "mkdir $pkg"
373 write_hello_library_files "$pkg"
374
cushon998b4102019-04-01 08:59:07 -0700375 bazel build //$pkg/java/main:main_deploy.jar || fail "build failed"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000376 ${PRODUCT_NAME}-bin/$pkg/java/main/main --singlejar \
377 | grep -q "Hello, Library!;Hello, World!" || fail "comparison failed"
378
379 unzip -p ${PRODUCT_NAME}-bin/$pkg/java/main/main_deploy.jar META-INF/MANIFEST.MF \
380 | grep -q "k1: v1" || fail "missing manifest lines"
381 unzip -p ${PRODUCT_NAME}-bin/$pkg/java/main/main_deploy.jar META-INF/MANIFEST.MF \
382 | grep -q "k2: v2" || fail "missing manifest lines"
383}
384
385function test_building_deploy_jar_twice_does_not_rebuild() {
386 local -r pkg="${FUNCNAME[0]}"
387 mkdir "$pkg" || fail "mkdir $pkg"
388 write_hello_library_files "$pkg"
389
cushon998b4102019-04-01 08:59:07 -0700390 bazel build //$pkg/java/main:main_deploy.jar || fail "build failed"
Klaus Aehligea6d06f2017-07-05 10:51:18 -0400391 touch -r ${PRODUCT_NAME}-bin/$pkg/java/main/main_deploy.jar old
cushon998b4102019-04-01 08:59:07 -0700392 bazel build //$pkg/java/main:main_deploy.jar || fail "build failed"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000393 find ${PRODUCT_NAME}-bin/$pkg/java/main/main_deploy.jar -newer old \
394 | grep -q . && fail "file was rebuilt"
395
396 true # reset the last exit code so the test won't be considered failed
397}
398
399function test_does_not_create_executable_when_not_asked_for() {
400 local -r pkg="${FUNCNAME[0]}"
401 mkdir "$pkg" || fail "mkdir $pkg"
402 write_hello_sailor_files "$pkg"
403
cushon998b4102019-04-01 08:59:07 -0700404 bazel build //$pkg/java/hellosailor:hellosailor_deploy.jar \
Laszlo Csomor68c86562016-09-19 12:59:16 +0000405 || fail "build failed"
406
407 if [[ ! -e ${PRODUCT_NAME}-bin/$pkg/java/hellosailor/hellosailor.jar ]]; then
408 fail "output jar does not exist";
409 fi
410
411 if [[ -e ${PRODUCT_NAME}-bin/$pkg/java/hellosailor/hellosailor ]]; then
412 fail "output executable should not exist";
413 fi
414
415 if [[ ! -e ${PRODUCT_NAME}-bin/$pkg/java/hellosailor/hellosailor_deploy.jar ]]; then
416 fail "output deploy jar does not exist";
417 fi
418
419}
420
Tetsuo Kiso122a7832022-09-13 02:12:24 -0700421# Assert that a deploy jar can be a dependency of another java_binary.
Laszlo Csomor68c86562016-09-19 12:59:16 +0000422function test_building_deploy_jar_dependent_on_deploy_jar() {
423 local -r pkg="${FUNCNAME[0]}"
424 mkdir -p $pkg/java/deploy || fail "mkdir"
425 cat > $pkg/java/deploy/BUILD <<EOF
426java_binary(name = 'Hello',
427 srcs = ['Hello.java'],
428 deps = ['Other_deploy.jar'],
429 main_class = 'hello.Hello')
430java_binary(name = 'Other',
431 resources = ['//$pkg/hello:Test.txt'],
432 main_class = 'none')
433EOF
434
435 cat >$pkg/java/deploy/Hello.java <<EOF
436package deploy;
437public class Hello {
438 public static void main(String[] args) {
439 System.out.println("Hello, World!");
440 }
441}
442EOF
443
444 mkdir -p $pkg/hello
445 echo "exports_files(['Test.txt'])" >$pkg/hello/BUILD
446 echo "Some other File" >$pkg/hello/Test.txt
447
cushon998b4102019-04-01 08:59:07 -0700448 bazel build //$pkg/java/deploy:Hello_deploy.jar || fail "build failed"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000449 unzip -p ${PRODUCT_NAME}-bin/$pkg/java/deploy/Hello_deploy.jar \
450 $pkg/hello/Test.txt | grep -q "Some other File" || fail "missing resource"
451}
452
453function test_wrapper_script_arg_handling() {
454 local -r pkg="${FUNCNAME[0]}"
455 mkdir -p $pkg/java/hello/ || fail "Expected success"
456 cat > $pkg/java/hello/Test.java <<EOF
457package hello;
458public class Test {
459 public static void main(String[] args) {
460 System.out.print("Args:");
461 for (String arg : args) {
462 System.out.print(" '" + arg + "'");
463 }
464 System.out.println();
465 }
466}
467EOF
468
469 cat > $pkg/java/hello/BUILD <<EOF
470java_binary(name='hello', srcs=['Test.java'], main_class='hello.Test')
471EOF
472
cushon998b4102019-04-01 08:59:07 -0700473 bazel run //$pkg/java/hello:hello -- '' foo '' '' 'bar quux' '' \
Laszlo Csomor68c86562016-09-19 12:59:16 +0000474 >&$TEST_log || fail "Build failed"
475 expect_log "Args: '' 'foo' '' '' 'bar quux' ''"
476}
477
478function test_srcjar_compilation() {
479 local -r pkg="${FUNCNAME[0]}"
480 mkdir -p $pkg/java/hello/ || fail "Expected success"
481 cat > $pkg/java/hello/Test.java <<EOF
482package hello;
483public class Test {
484 public static void main(String[] args) {
485 System.out.println("Hello World!");
486 }
487}
488EOF
489 cd $pkg
490 zip -q java/hello/test.srcjar java/hello/Test.java || fail "zip failed"
491 cd ..
492
493 cat > $pkg/java/hello/BUILD <<EOF
494java_binary(name='hello', srcs=['test.srcjar'], main_class='hello.Test')
495EOF
cushon998b4102019-04-01 08:59:07 -0700496 bazel build //$pkg/java/hello:hello //$pkg/java/hello:hello_deploy.jar \
Laszlo Csomor68c86562016-09-19 12:59:16 +0000497 >&$TEST_log || fail "Expected success"
cushon998b4102019-04-01 08:59:07 -0700498 bazel run //$pkg/java/hello:hello -- --singlejar >&$TEST_log
Laszlo Csomor68c86562016-09-19 12:59:16 +0000499 expect_log "Hello World!"
500}
501
502function test_private_initializers() {
503 local -r pkg="${FUNCNAME[0]}"
504 mkdir -p $pkg/java/hello/ || fail "Expected success"
505
506 cat > $pkg/java/hello/A.java <<EOF
507package hello;
508public class A { private B b; }
509EOF
510
511 cat > $pkg/java/hello/B.java <<EOF
512package hello;
513public class B { private C c; }
514EOF
515
516 cat > $pkg/java/hello/C.java <<EOF
517package hello;
518public class C {}
519EOF
520
521 # This definition is only to make sure that A's interface is built.
522 cat > $pkg/java/hello/App.java <<EOF
523package hello;
524public class App { }
525EOF
526
527 cat > $pkg/java/hello/BUILD <<EOF
528java_library(name = 'app',
529 srcs = ['App.java'],
530 deps = [':a'])
531
532java_library(name = 'a',
533 srcs = ['A.java'],
534 deps = [':b'])
535
536java_library(name = 'b',
537 srcs = ['B.java'],
538 deps = [':c'])
539
540java_library(name = 'c',
541 srcs = ['C.java'])
542EOF
543
544 bazel build //$pkg/java/hello:app || fail "Expected success"
545}
546
547function test_java_plugin() {
548 local -r pkg="${FUNCNAME[0]}"
549 mkdir -p $pkg/java/test/processor || fail "mkdir"
550
551 cat >$pkg/java/test/processor/BUILD <<EOF
552package(default_visibility=['//visibility:public'])
553
554java_library(name = 'annotation',
555 srcs = [ 'TestAnnotation.java' ])
556
557java_library(name = 'processor_dep',
558 srcs = [ 'ProcessorDep.java' ])
559
560java_plugin(name = 'processor',
561 processor_class = 'test.processor.Processor',
562 deps = [ ':annotation', ':processor_dep' ],
563 srcs = [ 'Processor.java' ])
564EOF
565
566 cat >$pkg/java/test/processor/TestAnnotation.java <<EOF
567package test.processor;
568import java.lang.annotation.*;
569@Target(value = {ElementType.TYPE})
570
571public @interface TestAnnotation {
572}
573EOF
574
575 cat >$pkg/java/test/processor/ProcessorDep.java <<EOF
576package test.processor;
577
578class ProcessorDep {
579 static String value = "DependencyValue";
580}
581EOF
582
583 cat >$pkg/java/test/processor/Processor.java <<EOF
584package test.processor;
585import java.util.*;
586import java.io.*;
587import javax.annotation.processing.*;
588import javax.tools.*;
589import javax.lang.model.*;
590import javax.lang.model.element.*;
591@SupportedAnnotationTypes(value= {"test.processor.TestAnnotation"})
592public class Processor extends AbstractProcessor {
Googlerb1457bb2023-06-09 12:15:12 -0700593 @Override
594 public SourceVersion getSupportedSourceVersion() {
595 return SourceVersion.latestSupported();
596 }
Laszlo Csomor68c86562016-09-19 12:59:16 +0000597 private static final String OUTFILE_CONTENT = "package test;\n"
598 + "public class Generated {\n"
599 + " public static String value = \"" + ProcessorDep.value + "\";\n"
600 + "}";
601 private ProcessingEnvironment mainEnvironment;
602 public void init(ProcessingEnvironment environment) {
603 mainEnvironment = environment;
604 }
605 public boolean process(Set<? extends TypeElement> annotations,
606 RoundEnvironment roundEnv) {
607 Filer filer = mainEnvironment.getFiler();
608 try {
609 FileObject output = filer.createSourceFile("test.Generated");
610 Writer writer = output.openWriter();
611 writer.append(OUTFILE_CONTENT);
612 writer.close();
613 } catch (IOException ex) {
614 return false;
615 }
616 return true;
617 }
618}
619EOF
620
621 mkdir -p $pkg/java/test/client
622 cat >$pkg/java/test/client/BUILD <<EOF
623java_library(name = 'client',
624 srcs = [ 'ProcessorClient.java' ],
625 deps = [ '//$pkg/java/test/processor:annotation' ],
626 plugins = [ '//$pkg/java/test/processor:processor' ])
627EOF
628
629 cat >$pkg/java/test/client/ProcessorClient.java <<EOF
630package test.client;
631import test.processor.TestAnnotation;
632@TestAnnotation()
633class ProcessorClient { }
634EOF
635
cushon998b4102019-04-01 08:59:07 -0700636 bazel build //$pkg/java/test/client:client --use_ijars || fail "build failed"
Damien Martin-Guillerezab588d22016-10-18 11:45:16 +0000637 unzip -l ${PRODUCT_NAME}-bin/$pkg/java/test/client/libclient.jar > $TEST_log
638 expect_log " test/Generated.class" "missing class file from annotation processing"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000639
cushon998b4102019-04-01 08:59:07 -0700640 bazel build //$pkg/java/test/client:libclient-src.jar --use_ijars \
Laszlo Csomor68c86562016-09-19 12:59:16 +0000641 || fail "build failed"
Damien Martin-Guillerezab588d22016-10-18 11:45:16 +0000642 unzip -l ${PRODUCT_NAME}-bin/$pkg/java/test/client/libclient-src.jar > $TEST_log
643 expect_log " test/Generated.java" "missing source file from annotation processing"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000644}
645
646function test_jvm_flags_are_passed_verbatim() {
647 local -r pkg="${FUNCNAME[0]}"
648 mkdir -p $pkg/java/com/google/jvmflags || fail "mkdir"
lberki6183faf2017-12-06 01:49:14 -0800649 cat >$pkg/java/com/google/jvmflags/BUILD <<EOF
Laszlo Csomor68c86562016-09-19 12:59:16 +0000650java_binary(
651 name = 'foo',
652 srcs = ['Foo.java'],
653 main_class = 'com.google.jvmflags.Foo',
lberki6183faf2017-12-06 01:49:14 -0800654 toolchains = ['${TOOLS_REPOSITORY}//tools/jdk:current_java_runtime'],
Laszlo Csomor68c86562016-09-19 12:59:16 +0000655 jvm_flags = [
656 # test quoting
lberki6183faf2017-12-06 01:49:14 -0800657 '--a=\\'single_single\\'',
Laszlo Csomor68c86562016-09-19 12:59:16 +0000658 '--b="single_double"',
659 "--c='double_single'",
lberki6183faf2017-12-06 01:49:14 -0800660 "--d=\\"double_double\\"",
Laszlo Csomor68c86562016-09-19 12:59:16 +0000661 '--e=no_quotes',
662 # no escaping expected
lberki6183faf2017-12-06 01:49:14 -0800663 '--f=stuff\$\$to"escape\\\\',
Laszlo Csomor68c86562016-09-19 12:59:16 +0000664 ],
665)
666EOF
667
668 cat >$pkg/java/com/google/jvmflags/Foo.java <<EOF
669package com.google.jvmflags;
670public class Foo { public static void main(String[] args) {} }
671EOF
672
cushon998b4102019-04-01 08:59:07 -0700673 bazel build //$pkg/java/com/google/jvmflags:foo || fail "build failed"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000674
675 STUBSCRIPT=${PRODUCT_NAME}-bin/$pkg/java/com/google/jvmflags/foo
676 [ -e $STUBSCRIPT ] || fail "$STUBSCRIPT not found"
677
678 for flag in \
679 " --a='single_single' " \
680 " --b=\"single_double\" " \
681 " --c='double_single' " \
682 " --d=\"double_double\" " \
683 ' --e=no_quotes ' \
684 ' --f=stuff$to"escape\\ ' \
Laszlo Csomor68c86562016-09-19 12:59:16 +0000685 ; do
686 # NOTE: don't test the full path of the JDK, it's architecture-dependent.
687 assert_contains $flag $STUBSCRIPT
688 done
689}
690
691function test_classpath_fiddling() {
692 local -r pkg="${FUNCNAME[0]}"
693 mkdir "$pkg" || fail "mkdir $pkg"
694 write_hello_library_files "$pkg"
695
696 mkdir -p $pkg/java/classpath
697 cat >$pkg/java/classpath/BUILD <<EOF
698java_binary(name = 'classpath',
699 deps = ['//$pkg/java/hello_library'],
700 srcs = ['Classpath.java'],
701 main_class = 'classpath.Classpath')
702EOF
703
704 cat >$pkg/java/classpath/Classpath.java <<'EOF'
705package classpath;
706public class Classpath {
707 public static void main(String[] args) {
708 String cp = System.getProperty("java.class.path");
709 String[] jars = cp.split(":"); // TODO(bazel-team): this is ";" on Windows
710 boolean singlejar
711 = (args.length > 1 && args[1].equals("SINGLEJAR"));
712 System.out.printf("CLASSPATH=%s%n", cp);
713 if (jars.length != 2 && !singlejar) {
714 throw new Error("Unexpected class path length");
715 }
716 String jarRegex = args[0];
717 for (String jar : jars) {
718 if (!jar.matches(jarRegex)) {
719 throw new Error("No match for regex: " + jarRegex);
720 }
721 if (!new java.io.File(jar).exists()) {
722 throw new Error("No such file: " + jar);
723 }
724 }
725 }
726}
727EOF
728
729 bazel clean
cushon998b4102019-04-01 08:59:07 -0700730 bazel build //$pkg/java/classpath || fail "build failed"
731 bazel run //$pkg/java/classpath -- \
Laszlo Csomor68c86562016-09-19 12:59:16 +0000732 "^$pkg/java/(classpath|hello_library)/.*\.jar\$" || fail "bazel run"
733
734 local PROG="${PRODUCT_NAME}-bin/$pkg/java/classpath/classpath"
735
736 function check_classpath_invocations() {
737 "$PROG" "^${PRODUCT_NAME}-bin/.*\.jar\$" "$@" \
738 || fail "direct run relative classpath $*"
739 "./$PROG" "^\./${PRODUCT_NAME}-bin/.*\.jar\$" "$@" \
740 || fail "direct run '.'-relative classpath $*"
741 "$PWD/$PROG" "^${PRODUCT_NAME}-bin/.*\.jar\$" "$@" \
742 || fail "direct run absolute classpath $*"
743 (PROG="$PWD/$PROG"; cd / && exec "$PROG" '^/.*\.jar$' "$@") \
744 || fail "direct run from / absolute classpath $*"
745 }
746
747 check_classpath_invocations
748
749 # Test --singlejar and --wrapper_script_flag
cushon998b4102019-04-01 08:59:07 -0700750 bazel build //$pkg/java/classpath:classpath_deploy.jar || fail "build failed"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000751 for prog in "$PROG" "./$PROG" "$PWD/$PROG"; do
752 "$prog" --singlejar '.*_deploy.jar$' "SINGLEJAR" \
753 || fail "$prog --singlejar"
754 "$prog" '.*_deploy.jar$' "SINGLEJAR" --wrapper_script_flag=--singlejar \
755 || fail "$prog --wrapper_script_flag=--singlejar"
756 done
757}
758
759function test_java7() {
760 local -r pkg="${FUNCNAME[0]}"
761 mkdir -p $pkg/java/foo/ || fail "Expected success"
762 cat > $pkg/java/foo/Foo.java <<EOF
763package foo;
764import java.lang.invoke.MethodHandle; // In Java 7 class library only
765import java.util.ArrayList;
766public class Foo {
767 public static void main(String[] args) {
768 ArrayList<Object> list = new ArrayList<>(); // In Java 7 language only
769 System.out.println("Success!");
770 }
771}
772EOF
773
774 cat > $pkg/java/foo/BUILD <<EOF
775java_binary(name = 'foo',
776 srcs = ['Foo.java'],
777 main_class = 'foo.Foo')
778EOF
779
cushon998b4102019-04-01 08:59:07 -0700780 bazel run //$pkg/java/foo:foo | grep -q "Success!" || fail "Expected success"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000781}
782
Laszlo Csomor68c86562016-09-19 12:59:16 +0000783function test_header_compilation() {
784 local -r pkg="${FUNCNAME[0]}"
785 mkdir "$pkg" || fail "mkdir $pkg"
786 write_hello_library_files "$pkg"
787
cushon998b4102019-04-01 08:59:07 -0700788 bazel build -s --java_header_compilation=true \
Laszlo Csomor68c86562016-09-19 12:59:16 +0000789 //$pkg/java/main:main || fail "build failed"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000790 unzip -l ${PRODUCT_NAME}-bin/$pkg/java/hello_library/libhello_library-hjar.jar \
Damien Martin-Guillerez45da3f12016-12-29 11:29:21 +0000791 > $TEST_log
792 expect_log " hello_library/HelloLibrary.class" \
793 "missing class file from header compilation"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000794}
795
796function test_header_compilation_errors() {
797 local -r pkg="${FUNCNAME[0]}"
798 mkdir -p $pkg/java/test/ || fail "Expected success"
799 cat > $pkg/java/test/A.java <<EOF
800package test;
801public class A {}
802EOF
803 cat > $pkg/java/test/B.java <<EOF
804package test;
805import missing.NoSuch;
806@NoSuch
807public class B {}
808EOF
809 cat > $pkg/java/test/BUILD <<EOF
810java_library(
811 name='a',
812 srcs=['A.java'],
813 deps=[':b'],
814)
815java_library(
816 name='b',
817 srcs=['B.java'],
818)
819EOF
cushon998b4102019-04-01 08:59:07 -0700820 bazel build --java_header_compilation=true \
cushonb274a7f2018-10-07 14:34:56 -0700821 //$pkg/java/test:liba.jar >& "$TEST_log" && fail "Unexpected success"
cushonbc167472018-10-12 11:35:12 -0700822 expect_log "symbol not found missing.NoSuch"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000823}
824
Googler26ec43d2022-10-25 08:17:12 -0700825function test_java_import_with_empty_jars_attribute() {
826 local -r pkg="${FUNCNAME[0]}"
827 mkdir -p $pkg/java/hello/ || fail "Expected success"
828 cat > $pkg/java/hello/Hello.java <<EOF
829package hello;
830public class Hello {
831 public static void main(String[] args) {
832 System.out.println("Hello World!");
833 }
834}
835EOF
836 cat > $pkg/java/hello/BUILD <<EOF
837java_import(
838 name='empty_java_import',
839 jars=[]
840)
841java_binary(
842 name='hello',
843 srcs=['Hello.java'],
844 deps=[':empty_java_import'],
845 main_class = 'hello.Hello'
846)
847EOF
848 bazel build --incompatible_disallow_java_import_empty_jars=0 //$pkg/java/hello:hello //$pkg/java/hello:hello_deploy.jar >& "$TEST_log" \
849 || fail "Expected success"
Googlerb7401892022-11-08 09:44:59 -0800850 bazel run --incompatible_disallow_java_import_empty_jars=0 //$pkg/java/hello:hello -- --singlejar >& "$TEST_log"
Googler26ec43d2022-10-25 08:17:12 -0700851 expect_log "Hello World!"
852}
853
cushonbd225232020-07-01 11:41:40 -0700854function test_arg_compile_action() {
855 local package="${FUNCNAME[0]}"
856 mkdir -p "${package}"
857
858 cat > "${package}/lib.bzl" <<EOF
859def _actions_test_impl(target, ctx):
860 action = target.actions[0] # digest action
861 if action.mnemonic != "Javac":
862 fail("Expected the first action to be Javac.")
863 aspect_out = ctx.actions.declare_file('aspect_out')
864 ctx.actions.run_shell(inputs = action.inputs,
865 outputs = [aspect_out],
866 command = "echo \$@ > " + aspect_out.path,
867 arguments = action.args)
868 return [OutputGroupInfo(out=[aspect_out])]
869
870actions_test_aspect = aspect(implementation = _actions_test_impl)
871EOF
872
873 touch "${package}/x.java"
874 cat > "${package}/BUILD" <<EOF
875java_library(
876 name = "x",
877 srcs = ["x.java"],
878)
879EOF
880
881 bazel build "${package}:x" \
882 --aspects="//${package}:lib.bzl%actions_test_aspect" \
laurentlb39bc97e2020-08-13 09:25:03 -0700883 --output_groups=out
cushonbd225232020-07-01 11:41:40 -0700884
885 cat "${PRODUCT_NAME}-bin/${package}/aspect_out" | grep "0.params .*1.params" \
886 || fail "aspect Args do not contain both params files"
887}
888
Laszlo Csomor68c86562016-09-19 12:59:16 +0000889run_suite "Java integration tests"