blob: 108e67b98fd7314c8ff3176c32df210b1d7cd124 [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
Laszlo Csomor68c86562016-09-19 12:59:16 +000026set -eu
27
28declare -r runfiles_relative_javabase="$1"
Luis Fernando Pino Duquefa389062016-10-18 14:28:42 +000029add_to_bazelrc "build --package_path=%workspace%"
Laszlo Csomor68c86562016-09-19 12:59:16 +000030
31#### HELPER FUNCTIONS ##################################################
32
33function setup_local_jdk() {
34 local -r dest="$1"
35 local -r src="${BAZEL_RUNFILES}/${runfiles_relative_javabase}"
36
37 mkdir -p "$dest" || fail "mkdir -p $dest"
38 cp -LR "${src}"/* "$dest" || fail "cp -LR \"${src}\"/* \"$dest\""
39 chmod -R ug+rwX "$dest" || fail "chmod -R ug+rwX \"$dest\""
40}
41
42function write_hello_world_files() {
43 local pkg="$1"
44 mkdir -p $pkg/java/hello || fail "mkdir"
45 cat >$pkg/java/hello/BUILD <<EOF
46java_binary(name = 'hello',
47 srcs = ['Hello.java'],
48 main_class = 'hello.Hello')
49EOF
50
51 cat >$pkg/java/hello/Hello.java <<EOF
52package hello;
53public class Hello {
54 public static void main(String[] args) {
55 System.out.println("Hello, World!");
56 }
57}
58EOF
59}
60
61function write_hello_world_files_for_singlejar() {
62 local -r pkg="$1"
63 mkdir -p $pkg/java/hello || fail "mkdir"
64 cat >$pkg/java/hello/BUILD <<EOF
65java_binary(name = 'hello',
66 srcs = ['Hello.java'],
67 main_class = 'hello.Hello')
68EOF
69
70 cat >$pkg/java/hello/Hello.java <<EOF
71package hello;
72import java.util.Properties;
73public class Hello {
74 private static void printMap(Properties p) {
75 System.err.println("Available keys and values are:");
76 for (Object key : p.keySet()) {
77 System.err.printf(" '%s': '%s'%n", key, p.get(key));
78 }
79 }
80
81 public static void main(String[] args) throws Exception {
82 Properties properties = new Properties();
83 properties.load(Hello.class.getResourceAsStream("/build-data.properties"));
84 for (String arg : args) {
85 String[] keyValue = arg.split("=", 2);
86 Object value = properties.get(keyValue[0]);
87 if (value == null) {
88 System.err.println("Key '" + keyValue[0] + "' not found");
89 printMap(properties);
90 return;
91 }
92 if (keyValue.length > 1 && !keyValue[1].equals(value)) {
93 System.err.println("Value for key '" + keyValue[0] + "' is '" + value
94 + "' while it should be '" + keyValue[1] + "'");
95 printMap(properties);
96 return;
97 }
98 }
99 System.out.println("Hello, World!");
100 }
101}
102EOF
103}
104
105function write_hello_library_files() {
106 local -r pkg="$1"
107 mkdir -p $pkg/java/main || fail "mkdir"
108 cat >$pkg/java/main/BUILD <<EOF
109java_binary(
110 name = 'main',
111 deps = ['//$pkg/java/hello_library'],
112 srcs = ['Main.java'],
113 main_class = 'main.Main',
114 deploy_manifest_lines = ['k1: v1', 'k2: v2'])
115EOF
116
117 cat >$pkg/java/main/Main.java <<EOF
118package main;
119import hello_library.HelloLibrary;
120public class Main {
121 public static void main(String[] args) {
122 HelloLibrary.funcHelloLibrary();
123 System.out.println("Hello, World!");
124 }
125}
126EOF
127
128 mkdir -p $pkg/java/hello_library || fail "mkdir"
129 cat >$pkg/java/hello_library/BUILD <<EOF
130package(default_visibility=['//visibility:public'])
131java_library(name = 'hello_library',
132 srcs = ['HelloLibrary.java']);
133EOF
134
135 cat >$pkg/java/hello_library/HelloLibrary.java <<EOF
136package hello_library;
137public class HelloLibrary {
138 public static void funcHelloLibrary() {
139 System.out.print("Hello, Library!;");
140 }
141}
142EOF
143}
144
145function write_hello_sailor_files() {
146 local -r pkg="$1"
147 mkdir -p $pkg/java/hellosailor || fail "mkdir"
148 cat >$pkg/java/hellosailor/BUILD <<EOF
149java_binary(name = 'hellosailor',
150 srcs = ['HelloSailor.java'],
151 create_executable = 0)
152EOF
153
154 cat >$pkg/java/hellosailor/HelloSailor.java <<EOF
155package hellosailor;
156public class HelloSailor {
157 public static int addtwoNumbers(int a, int b) {
158 return a + b;
159 }
160}
161EOF
162}
163
164
165#### TESTS #############################################################
166
167# This test intentionally show some errors on the standard output.
168function test_compiles_hello_world() {
169 local -r pkg="${FUNCNAME[0]}"
170 mkdir "$pkg" || fail "mkdir $pkg"
171 write_hello_world_files "$pkg"
172
173 bazel clean
174 bazel build //$pkg/java/hello:hello || fail "build failed"
175 ${PRODUCT_NAME}-bin/$pkg/java/hello/hello | grep -q 'Hello, World!' \
176 || fail "comparison failed"
177 function check_deploy_jar_should_not_exist() {
178 "$@" && fail "deploy jar should not exist"
179 true # reset the last exit code so the test won't be considered failed
180 }
181 function check_arglists() {
182 check_deploy_jar_should_not_exist "$@" --singlejar
183 check_deploy_jar_should_not_exist "$@" --wrapper_script_flag=--singlejar
184 check_deploy_jar_should_not_exist "$@" REGULAR_ARG \
185 --wrapper_script_flag=--singlejar
186 }
187 check_arglists bazel run //$pkg/java/hello:hello --
188 check_arglists ${PRODUCT_NAME}-bin/$pkg/java/hello/hello
189}
190
191function test_compiles_hello_world_from_deploy_jar() {
192 local -r pkg="${FUNCNAME[0]}"
193 mkdir "$pkg" || fail "mkdir $pkg"
194 write_hello_world_files "$pkg"
195
196 bazel build //$pkg/java/hello:hello_deploy.jar || fail "build failed"
Luis Fernando Pino Duquefa389062016-10-18 14:28:42 +0000197
198 bazel run //$pkg/java/hello:hello -- --singlejar | grep -q 'Hello, World!' \
199 || fail "comparison failed"
200 ${PRODUCT_NAME}-bin/$pkg/java/hello/hello -- --singlejar | \
201 grep -q 'Hello, World!' || fail "comparison failed"
202
203 bazel run //$pkg/java/hello:hello -- --wrapper_script_flag=--singlejar \
204 | grep -q 'Hello, World!' || fail "comparison failed"
205 ${PRODUCT_NAME}-bin/$pkg/java/hello/hello -- \
206 --wrapper_script_flag=--singlejar | grep -q 'Hello, World!' \
207 || fail "comparison failed"
208
209 bazel run //$pkg/java/hello:hello -- REGULAR_ARG \
210 --wrapper_script_flag=--singlejar | grep -q 'Hello, World!' \
211 || fail "comparison failed"
212 ${PRODUCT_NAME}-bin/$pkg/java/hello/hello -- REGULAR_ARG \
213 --wrapper_script_flag=--singlejar | grep -q 'Hello, World!' \
214 || fail "comparison failed"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000215}
216
217function test_explicit_bogus_wrapper_args_are_rejected() {
218 local -r pkg="${FUNCNAME[0]}"
219 mkdir "$pkg" || fail "mkdir $pkg"
220 write_hello_world_files "$pkg"
221
222 bazel build //$pkg/java/hello:hello_deploy.jar || fail "build failed"
223 function check_arg_rejected() {
224 "$@" && fail "bogus arg should be rejected"
225 true # reset the last exit code so the test won't be considered failed
226 }
227 function check_arglists() {
228 check_arg_rejected "$@" --wrapper_script_flag=--bogus
229 check_arg_rejected "$@" REGULAR_ARG --wrapper_script_flag=--bogus
230 }
231 check_arglists bazel run //$pkg/java/hello:hello --
232 check_arglists ${PRODUCT_NAME}-bin/$pkg/java/hello/hello
233}
234
235function assert_singlejar_works() {
236 local -r pkg="$1"
237 local -r copy_jdk="$2"
238 local -r stamp_arg="$3"
239 local -r embed_label="$4"
240 local -r expected_build_data="$5"
241
242 write_hello_world_files_for_singlejar "$pkg"
243
244 if "$copy_jdk"; then
245 local -r local_jdk="$pkg/my_jdk"
246 setup_local_jdk "$local_jdk"
247
248 ln -s "my_jdk" "$pkg/my_jdk.symlink"
249 local -r javabase="$(get_real_path "$pkg/my_jdk.symlink")"
250 else
251 local -r javabase="${BAZEL_RUNFILES}/${runfiles_relative_javabase}"
252 fi
253
lberki2ea4fa22017-10-11 11:42:53 +0200254 mkdir -p "$pkg/jvm"
255 cat > "$pkg/jvm/BUILD" <<EOF
256package(default_visibility=["//visibility:public"])
lberki2ea4fa22017-10-11 11:42:53 +0200257java_runtime(name='runtime', java_home='$javabase')
258EOF
259
260
Laszlo Csomor68c86562016-09-19 12:59:16 +0000261 # Set javabase to an absolute path.
262 bazel build //$pkg/java/hello:hello //$pkg/java/hello:hello_deploy.jar \
cushon6e0466f2018-07-05 11:54:59 -0700263 "$stamp_arg" --javabase="//$pkg/jvm:runtime" "$embed_label" >&"$TEST_log" \
Laszlo Csomor68c86562016-09-19 12:59:16 +0000264 || fail "Build failed"
265
266 mkdir $pkg/ugly/ || fail "mkdir failed"
267 # The stub script follows symlinks, so copy the files.
268 cp ${PRODUCT_NAME}-bin/$pkg/java/hello/hello $pkg/ugly/
269 cp ${PRODUCT_NAME}-bin/$pkg/java/hello/hello_deploy.jar $pkg/ugly/
270
271 $pkg/ugly/hello build.target build.time build.timestamp \
Androbin9c78a792017-11-29 01:31:47 -0800272 main.class=hello.Hello "$expected_build_data" >> $TEST_log 2>&1
Laszlo Csomor68c86562016-09-19 12:59:16 +0000273 expect_log 'Hello, World!'
274}
275
276function test_singlejar_with_default_jdk_with_stamp() {
277 local -r pkg="${FUNCNAME[0]}"
278 assert_singlejar_works "$pkg" true "--stamp" "--embed_label=toto" \
279 "build.label=toto"
280}
281
282# Regression test for b/17658100, ensure that --nostamp generate correct
283# build-info.properties file.
284function test_singlejar_with_default_jdk_without_stamp() {
285 local -r pkg="${FUNCNAME[0]}"
286 assert_singlejar_works "$pkg" true "--nostamp" "--embed_label=" \
287 "build.timestamp.as.int=0"
288}
289
290# Regression test for b/3244955, to ensure that running the deploy jar works
291# even without the runfiles available.
292function test_singlejar_with_custom_jdk_with_stamp() {
293 local -r pkg="${FUNCNAME[0]}"
294 assert_singlejar_works "$pkg" false "--stamp" "--embed_label=toto" \
295 "build.label=toto"
296}
297
298function test_singlejar_with_custom_jdk_without_stamp() {
299 local -r pkg="${FUNCNAME[0]}"
300 assert_singlejar_works "$pkg" false "--nostamp" "--embed_label=" \
301 "build.timestamp.as.int=0"
302}
303
304# Regression test for b/18191163: ensure that the build is deterministic when
305# used with --nostamp.
306function test_deterministic_nostamp_build() {
307 local -r pkg="${FUNCNAME[0]}"
308 mkdir "$pkg" || fail "mkdir $pkg"
309 write_hello_world_files "$pkg"
310
311 bazel clean || fail "Clean failed"
312 bazel build --nostamp //$pkg/java/hello:hello_deploy.jar \
313 || fail "Build failed"
Xin Gao33d05f62017-06-21 17:13:23 +0200314 # TODO(bazel-team) .a files (C/C++ static library file generated by
315 # archive tool) on darwin OS only are not deterministic.
316 # https://github.com/bazelbuild/bazel/issues/3156
Laszlo Csomor68c86562016-09-19 12:59:16 +0000317 local -r first_run="$(md5_file $(find "${PRODUCT_NAME}-out/" -type f '!' \
Xin Gao33d05f62017-06-21 17:13:23 +0200318 -name build-changelist.txt -a '!' -name volatile-status.txt \
Androbinef381e52017-12-14 07:24:27 -0800319 -a '!' -name 'stderr-*' -a '!' -name '*.a' \
Xin Gao33d05f62017-06-21 17:13:23 +0200320 -a '!' -name __xcodelocatorcache -a '!' -name __xcruncache \
321 | sort -u))"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000322
323 sleep 1 # Ensure the timestamp change between builds.
324
325 bazel clean || fail "Clean failed"
326 bazel build --nostamp //$pkg/java/hello:hello_deploy.jar \
327 || fail "Build failed"
328 local -r second_run="$(md5_file $(find "${PRODUCT_NAME}-out/" -type f '!' \
Xin Gao33d05f62017-06-21 17:13:23 +0200329 -name build-changelist.txt -a '!' -name volatile-status.txt \
Androbinef381e52017-12-14 07:24:27 -0800330 -a '!' -name 'stderr-*' -a '!' -name '*.a' \
Xin Gao33d05f62017-06-21 17:13:23 +0200331 -a '!' -name __xcodelocatorcache -a '!' -name __xcruncache \
332 | sort -u))"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000333
334 assert_equals "$first_run" "$second_run"
335}
336
337function test_compiles_hello_library() {
338 local -r pkg="${FUNCNAME[0]}"
339 mkdir "$pkg" || fail "mkdir $pkg"
340 write_hello_library_files "$pkg"
341
342 bazel clean
343 bazel build //$pkg/java/main:main || fail "build failed"
344 ${PRODUCT_NAME}-bin/$pkg/java/main/main \
345 | grep -q "Hello, Library!;Hello, World!" || fail "comparison failed"
346 bazel run //$pkg/java/main:main -- --singlejar && fail "deploy jar should not exist"
347
348 true # reset the last exit code so the test won't be considered failed
349}
350
351function test_compiles_hello_library_using_ijars() {
352 local -r pkg="${FUNCNAME[0]}"
353 mkdir "$pkg" || fail "mkdir $pkg"
354 write_hello_library_files "$pkg"
355
356 bazel clean
357 bazel build --use_ijars //$pkg/java/main:main || fail "build failed"
358 ${PRODUCT_NAME}-bin/$pkg/java/main/main \
359 | grep -q "Hello, Library!;Hello, World!" || fail "comparison failed"
360}
361
362function test_compiles_hello_library_from_deploy_jar() {
363 local -r pkg="${FUNCNAME[0]}"
364 mkdir "$pkg" || fail "mkdir $pkg"
365 write_hello_library_files "$pkg"
366
367 bazel build //$pkg/java/main:main_deploy.jar || fail "build failed"
368 ${PRODUCT_NAME}-bin/$pkg/java/main/main --singlejar \
369 | grep -q "Hello, Library!;Hello, World!" || fail "comparison failed"
370
371 unzip -p ${PRODUCT_NAME}-bin/$pkg/java/main/main_deploy.jar META-INF/MANIFEST.MF \
372 | grep -q "k1: v1" || fail "missing manifest lines"
373 unzip -p ${PRODUCT_NAME}-bin/$pkg/java/main/main_deploy.jar META-INF/MANIFEST.MF \
374 | grep -q "k2: v2" || fail "missing manifest lines"
375}
376
377function test_building_deploy_jar_twice_does_not_rebuild() {
378 local -r pkg="${FUNCNAME[0]}"
379 mkdir "$pkg" || fail "mkdir $pkg"
380 write_hello_library_files "$pkg"
381
382 bazel build //$pkg/java/main:main_deploy.jar || fail "build failed"
Klaus Aehligea6d06f2017-07-05 10:51:18 -0400383 touch -r ${PRODUCT_NAME}-bin/$pkg/java/main/main_deploy.jar old
Laszlo Csomor68c86562016-09-19 12:59:16 +0000384 bazel build //$pkg/java/main:main_deploy.jar || fail "build failed"
385 find ${PRODUCT_NAME}-bin/$pkg/java/main/main_deploy.jar -newer old \
386 | grep -q . && fail "file was rebuilt"
387
388 true # reset the last exit code so the test won't be considered failed
389}
390
391function test_does_not_create_executable_when_not_asked_for() {
392 local -r pkg="${FUNCNAME[0]}"
393 mkdir "$pkg" || fail "mkdir $pkg"
394 write_hello_sailor_files "$pkg"
395
396 bazel build //$pkg/java/hellosailor:hellosailor_deploy.jar \
397 || fail "build failed"
398
399 if [[ ! -e ${PRODUCT_NAME}-bin/$pkg/java/hellosailor/hellosailor.jar ]]; then
400 fail "output jar does not exist";
401 fi
402
403 if [[ -e ${PRODUCT_NAME}-bin/$pkg/java/hellosailor/hellosailor ]]; then
404 fail "output executable should not exist";
405 fi
406
407 if [[ ! -e ${PRODUCT_NAME}-bin/$pkg/java/hellosailor/hellosailor_deploy.jar ]]; then
408 fail "output deploy jar does not exist";
409 fi
410
411}
412
413# Assert that the a deploy jar can be a dependency of another java_binary.
414function test_building_deploy_jar_dependent_on_deploy_jar() {
415 local -r pkg="${FUNCNAME[0]}"
416 mkdir -p $pkg/java/deploy || fail "mkdir"
417 cat > $pkg/java/deploy/BUILD <<EOF
418java_binary(name = 'Hello',
419 srcs = ['Hello.java'],
420 deps = ['Other_deploy.jar'],
421 main_class = 'hello.Hello')
422java_binary(name = 'Other',
423 resources = ['//$pkg/hello:Test.txt'],
424 main_class = 'none')
425EOF
426
427 cat >$pkg/java/deploy/Hello.java <<EOF
428package deploy;
429public class Hello {
430 public static void main(String[] args) {
431 System.out.println("Hello, World!");
432 }
433}
434EOF
435
436 mkdir -p $pkg/hello
437 echo "exports_files(['Test.txt'])" >$pkg/hello/BUILD
438 echo "Some other File" >$pkg/hello/Test.txt
439
440 bazel build //$pkg/java/deploy:Hello_deploy.jar || fail "build failed"
441 unzip -p ${PRODUCT_NAME}-bin/$pkg/java/deploy/Hello_deploy.jar \
442 $pkg/hello/Test.txt | grep -q "Some other File" || fail "missing resource"
443}
444
445function test_wrapper_script_arg_handling() {
446 local -r pkg="${FUNCNAME[0]}"
447 mkdir -p $pkg/java/hello/ || fail "Expected success"
448 cat > $pkg/java/hello/Test.java <<EOF
449package hello;
450public class Test {
451 public static void main(String[] args) {
452 System.out.print("Args:");
453 for (String arg : args) {
454 System.out.print(" '" + arg + "'");
455 }
456 System.out.println();
457 }
458}
459EOF
460
461 cat > $pkg/java/hello/BUILD <<EOF
462java_binary(name='hello', srcs=['Test.java'], main_class='hello.Test')
463EOF
464
465 bazel run //$pkg/java/hello:hello -- '' foo '' '' 'bar quux' '' \
466 >&$TEST_log || fail "Build failed"
467 expect_log "Args: '' 'foo' '' '' 'bar quux' ''"
468}
469
470function test_srcjar_compilation() {
471 local -r pkg="${FUNCNAME[0]}"
472 mkdir -p $pkg/java/hello/ || fail "Expected success"
473 cat > $pkg/java/hello/Test.java <<EOF
474package hello;
475public class Test {
476 public static void main(String[] args) {
477 System.out.println("Hello World!");
478 }
479}
480EOF
481 cd $pkg
482 zip -q java/hello/test.srcjar java/hello/Test.java || fail "zip failed"
483 cd ..
484
485 cat > $pkg/java/hello/BUILD <<EOF
486java_binary(name='hello', srcs=['test.srcjar'], main_class='hello.Test')
487EOF
488 bazel build //$pkg/java/hello:hello //$pkg/java/hello:hello_deploy.jar \
489 >&$TEST_log || fail "Expected success"
490 bazel run //$pkg/java/hello:hello -- --singlejar >&$TEST_log
491 expect_log "Hello World!"
492}
493
494function test_private_initializers() {
495 local -r pkg="${FUNCNAME[0]}"
496 mkdir -p $pkg/java/hello/ || fail "Expected success"
497
498 cat > $pkg/java/hello/A.java <<EOF
499package hello;
500public class A { private B b; }
501EOF
502
503 cat > $pkg/java/hello/B.java <<EOF
504package hello;
505public class B { private C c; }
506EOF
507
508 cat > $pkg/java/hello/C.java <<EOF
509package hello;
510public class C {}
511EOF
512
513 # This definition is only to make sure that A's interface is built.
514 cat > $pkg/java/hello/App.java <<EOF
515package hello;
516public class App { }
517EOF
518
519 cat > $pkg/java/hello/BUILD <<EOF
520java_library(name = 'app',
521 srcs = ['App.java'],
522 deps = [':a'])
523
524java_library(name = 'a',
525 srcs = ['A.java'],
526 deps = [':b'])
527
528java_library(name = 'b',
529 srcs = ['B.java'],
530 deps = [':c'])
531
532java_library(name = 'c',
533 srcs = ['C.java'])
534EOF
535
536 bazel build //$pkg/java/hello:app || fail "Expected success"
537}
538
539function test_java_plugin() {
540 local -r pkg="${FUNCNAME[0]}"
541 mkdir -p $pkg/java/test/processor || fail "mkdir"
542
543 cat >$pkg/java/test/processor/BUILD <<EOF
544package(default_visibility=['//visibility:public'])
545
546java_library(name = 'annotation',
547 srcs = [ 'TestAnnotation.java' ])
548
549java_library(name = 'processor_dep',
550 srcs = [ 'ProcessorDep.java' ])
551
552java_plugin(name = 'processor',
553 processor_class = 'test.processor.Processor',
554 deps = [ ':annotation', ':processor_dep' ],
555 srcs = [ 'Processor.java' ])
556EOF
557
558 cat >$pkg/java/test/processor/TestAnnotation.java <<EOF
559package test.processor;
560import java.lang.annotation.*;
561@Target(value = {ElementType.TYPE})
562
563public @interface TestAnnotation {
564}
565EOF
566
567 cat >$pkg/java/test/processor/ProcessorDep.java <<EOF
568package test.processor;
569
570class ProcessorDep {
571 static String value = "DependencyValue";
572}
573EOF
574
575 cat >$pkg/java/test/processor/Processor.java <<EOF
576package test.processor;
577import java.util.*;
578import java.io.*;
579import javax.annotation.processing.*;
580import javax.tools.*;
581import javax.lang.model.*;
582import javax.lang.model.element.*;
583@SupportedAnnotationTypes(value= {"test.processor.TestAnnotation"})
584public class Processor extends AbstractProcessor {
585 private static final String OUTFILE_CONTENT = "package test;\n"
586 + "public class Generated {\n"
587 + " public static String value = \"" + ProcessorDep.value + "\";\n"
588 + "}";
589 private ProcessingEnvironment mainEnvironment;
590 public void init(ProcessingEnvironment environment) {
591 mainEnvironment = environment;
592 }
593 public boolean process(Set<? extends TypeElement> annotations,
594 RoundEnvironment roundEnv) {
595 Filer filer = mainEnvironment.getFiler();
596 try {
597 FileObject output = filer.createSourceFile("test.Generated");
598 Writer writer = output.openWriter();
599 writer.append(OUTFILE_CONTENT);
600 writer.close();
601 } catch (IOException ex) {
602 return false;
603 }
604 return true;
605 }
606}
607EOF
608
609 mkdir -p $pkg/java/test/client
610 cat >$pkg/java/test/client/BUILD <<EOF
611java_library(name = 'client',
612 srcs = [ 'ProcessorClient.java' ],
613 deps = [ '//$pkg/java/test/processor:annotation' ],
614 plugins = [ '//$pkg/java/test/processor:processor' ])
615EOF
616
617 cat >$pkg/java/test/client/ProcessorClient.java <<EOF
618package test.client;
619import test.processor.TestAnnotation;
620@TestAnnotation()
621class ProcessorClient { }
622EOF
623
624 bazel build //$pkg/java/test/client:client --use_ijars || fail "build failed"
Damien Martin-Guillerezab588d22016-10-18 11:45:16 +0000625 unzip -l ${PRODUCT_NAME}-bin/$pkg/java/test/client/libclient.jar > $TEST_log
626 expect_log " test/Generated.class" "missing class file from annotation processing"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000627
628 bazel build //$pkg/java/test/client:libclient-src.jar --use_ijars \
629 || fail "build failed"
Damien Martin-Guillerezab588d22016-10-18 11:45:16 +0000630 unzip -l ${PRODUCT_NAME}-bin/$pkg/java/test/client/libclient-src.jar > $TEST_log
631 expect_log " test/Generated.java" "missing source file from annotation processing"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000632}
633
634function test_jvm_flags_are_passed_verbatim() {
635 local -r pkg="${FUNCNAME[0]}"
636 mkdir -p $pkg/java/com/google/jvmflags || fail "mkdir"
lberki6183faf2017-12-06 01:49:14 -0800637 cat >$pkg/java/com/google/jvmflags/BUILD <<EOF
Laszlo Csomor68c86562016-09-19 12:59:16 +0000638java_binary(
639 name = 'foo',
640 srcs = ['Foo.java'],
641 main_class = 'com.google.jvmflags.Foo',
lberki6183faf2017-12-06 01:49:14 -0800642 toolchains = ['${TOOLS_REPOSITORY}//tools/jdk:current_java_runtime'],
Laszlo Csomor68c86562016-09-19 12:59:16 +0000643 jvm_flags = [
644 # test quoting
lberki6183faf2017-12-06 01:49:14 -0800645 '--a=\\'single_single\\'',
Laszlo Csomor68c86562016-09-19 12:59:16 +0000646 '--b="single_double"',
647 "--c='double_single'",
lberki6183faf2017-12-06 01:49:14 -0800648 "--d=\\"double_double\\"",
Laszlo Csomor68c86562016-09-19 12:59:16 +0000649 '--e=no_quotes',
650 # no escaping expected
lberki6183faf2017-12-06 01:49:14 -0800651 '--f=stuff\$\$to"escape\\\\',
Laszlo Csomor68c86562016-09-19 12:59:16 +0000652 ],
653)
654EOF
655
656 cat >$pkg/java/com/google/jvmflags/Foo.java <<EOF
657package com.google.jvmflags;
658public class Foo { public static void main(String[] args) {} }
659EOF
660
Dmitry Lomove36a66c2017-02-17 14:48:48 +0000661 bazel build //$pkg/java/com/google/jvmflags:foo || fail "build failed"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000662
663 STUBSCRIPT=${PRODUCT_NAME}-bin/$pkg/java/com/google/jvmflags/foo
664 [ -e $STUBSCRIPT ] || fail "$STUBSCRIPT not found"
665
666 for flag in \
667 " --a='single_single' " \
668 " --b=\"single_double\" " \
669 " --c='double_single' " \
670 " --d=\"double_double\" " \
671 ' --e=no_quotes ' \
672 ' --f=stuff$to"escape\\ ' \
Laszlo Csomor68c86562016-09-19 12:59:16 +0000673 ; do
674 # NOTE: don't test the full path of the JDK, it's architecture-dependent.
675 assert_contains $flag $STUBSCRIPT
676 done
677}
678
679function test_classpath_fiddling() {
680 local -r pkg="${FUNCNAME[0]}"
681 mkdir "$pkg" || fail "mkdir $pkg"
682 write_hello_library_files "$pkg"
683
684 mkdir -p $pkg/java/classpath
685 cat >$pkg/java/classpath/BUILD <<EOF
686java_binary(name = 'classpath',
687 deps = ['//$pkg/java/hello_library'],
688 srcs = ['Classpath.java'],
689 main_class = 'classpath.Classpath')
690EOF
691
692 cat >$pkg/java/classpath/Classpath.java <<'EOF'
693package classpath;
694public class Classpath {
695 public static void main(String[] args) {
696 String cp = System.getProperty("java.class.path");
697 String[] jars = cp.split(":"); // TODO(bazel-team): this is ";" on Windows
698 boolean singlejar
699 = (args.length > 1 && args[1].equals("SINGLEJAR"));
700 System.out.printf("CLASSPATH=%s%n", cp);
701 if (jars.length != 2 && !singlejar) {
702 throw new Error("Unexpected class path length");
703 }
704 String jarRegex = args[0];
705 for (String jar : jars) {
706 if (!jar.matches(jarRegex)) {
707 throw new Error("No match for regex: " + jarRegex);
708 }
709 if (!new java.io.File(jar).exists()) {
710 throw new Error("No such file: " + jar);
711 }
712 }
713 }
714}
715EOF
716
717 bazel clean
718 bazel build //$pkg/java/classpath || fail "build failed"
719 bazel run //$pkg/java/classpath -- \
720 "^$pkg/java/(classpath|hello_library)/.*\.jar\$" || fail "bazel run"
721
722 local PROG="${PRODUCT_NAME}-bin/$pkg/java/classpath/classpath"
723
724 function check_classpath_invocations() {
725 "$PROG" "^${PRODUCT_NAME}-bin/.*\.jar\$" "$@" \
726 || fail "direct run relative classpath $*"
727 "./$PROG" "^\./${PRODUCT_NAME}-bin/.*\.jar\$" "$@" \
728 || fail "direct run '.'-relative classpath $*"
729 "$PWD/$PROG" "^${PRODUCT_NAME}-bin/.*\.jar\$" "$@" \
730 || fail "direct run absolute classpath $*"
731 (PROG="$PWD/$PROG"; cd / && exec "$PROG" '^/.*\.jar$' "$@") \
732 || fail "direct run from / absolute classpath $*"
733 }
734
735 check_classpath_invocations
736
737 # Test --singlejar and --wrapper_script_flag
738 bazel build //$pkg/java/classpath:classpath_deploy.jar || fail "build failed"
739 for prog in "$PROG" "./$PROG" "$PWD/$PROG"; do
740 "$prog" --singlejar '.*_deploy.jar$' "SINGLEJAR" \
741 || fail "$prog --singlejar"
742 "$prog" '.*_deploy.jar$' "SINGLEJAR" --wrapper_script_flag=--singlejar \
743 || fail "$prog --wrapper_script_flag=--singlejar"
744 done
745}
746
747function test_java7() {
748 local -r pkg="${FUNCNAME[0]}"
749 mkdir -p $pkg/java/foo/ || fail "Expected success"
750 cat > $pkg/java/foo/Foo.java <<EOF
751package foo;
752import java.lang.invoke.MethodHandle; // In Java 7 class library only
753import java.util.ArrayList;
754public class Foo {
755 public static void main(String[] args) {
756 ArrayList<Object> list = new ArrayList<>(); // In Java 7 language only
757 System.out.println("Success!");
758 }
759}
760EOF
761
762 cat > $pkg/java/foo/BUILD <<EOF
763java_binary(name = 'foo',
764 srcs = ['Foo.java'],
765 main_class = 'foo.Foo')
766EOF
767
768 bazel run //$pkg/java/foo:foo | grep -q "Success!" || fail "Expected success"
769}
770
Laszlo Csomor68c86562016-09-19 12:59:16 +0000771function test_header_compilation() {
772 local -r pkg="${FUNCNAME[0]}"
773 mkdir "$pkg" || fail "mkdir $pkg"
774 write_hello_library_files "$pkg"
775
776 bazel build -s --java_header_compilation=true \
777 //$pkg/java/main:main || fail "build failed"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000778 unzip -l ${PRODUCT_NAME}-bin/$pkg/java/hello_library/libhello_library-hjar.jar \
Damien Martin-Guillerez45da3f12016-12-29 11:29:21 +0000779 > $TEST_log
780 expect_log " hello_library/HelloLibrary.class" \
781 "missing class file from header compilation"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000782}
783
784function test_header_compilation_errors() {
785 local -r pkg="${FUNCNAME[0]}"
786 mkdir -p $pkg/java/test/ || fail "Expected success"
787 cat > $pkg/java/test/A.java <<EOF
788package test;
789public class A {}
790EOF
791 cat > $pkg/java/test/B.java <<EOF
792package test;
793import missing.NoSuch;
794@NoSuch
795public class B {}
796EOF
797 cat > $pkg/java/test/BUILD <<EOF
798java_library(
799 name='a',
800 srcs=['A.java'],
801 deps=[':b'],
802)
803java_library(
804 name='b',
805 srcs=['B.java'],
806)
807EOF
808 bazel build --java_header_compilation=true \
809 //$pkg/java/test:a >& "$TEST_log" && fail "Unexpected success"
cushonb5099a22018-08-29 08:48:16 -0700810 expect_log "symbol not found missing.NoSuch"
Laszlo Csomor68c86562016-09-19 12:59:16 +0000811}
812
813function test_java_import_with_empty_jars_attribute() {
814 local -r pkg="${FUNCNAME[0]}"
815 mkdir -p $pkg/java/hello/ || fail "Expected success"
816 cat > $pkg/java/hello/Hello.java <<EOF
817package hello;
818public class Hello {
819 public static void main(String[] args) {
820 System.out.println("Hello World!");
821 }
822}
823EOF
824 cat > $pkg/java/hello/BUILD <<EOF
825java_import(
826 name='empty_java_import',
827 jars=[]
828)
829java_binary(
830 name='hello',
831 srcs=['Hello.java'],
832 deps=[':empty_java_import'],
833 main_class = 'hello.Hello'
834)
835EOF
836 bazel build //$pkg/java/hello:hello //$pkg/java/hello:hello_deploy.jar >& "$TEST_log" \
837 || fail "Expected success"
838 bazel run //$pkg/java/hello:hello -- --singlejar >& "$TEST_log"
839 expect_log "Hello World!"
840}
841
842run_suite "Java integration tests"