Fri, 17 May 2019 18:41:21 +0100
8218152: [javac] fails and exits with no error if a bad annotation processor provided
Summary: Handle exceptions thrown while loading annotation processors.
Reviewed-by: jlahoda, andrew
sgroeger@3814 | 1 | /* |
sgroeger@3814 | 2 | * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. |
sgroeger@3814 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
sgroeger@3814 | 4 | * |
sgroeger@3814 | 5 | * This code is free software; you can redistribute it and/or modify it |
sgroeger@3814 | 6 | * under the terms of the GNU General Public License version 2 only, as |
sgroeger@3814 | 7 | * published by the Free Software Foundation. |
sgroeger@3814 | 8 | * |
sgroeger@3814 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
sgroeger@3814 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
sgroeger@3814 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
sgroeger@3814 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
sgroeger@3814 | 13 | * accompanied this code). |
sgroeger@3814 | 14 | * |
sgroeger@3814 | 15 | * You should have received a copy of the GNU General Public License version |
sgroeger@3814 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
sgroeger@3814 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
sgroeger@3814 | 18 | * |
sgroeger@3814 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
sgroeger@3814 | 20 | * or visit www.oracle.com if you need additional information or have any |
sgroeger@3814 | 21 | * questions. |
sgroeger@3814 | 22 | */ |
sgroeger@3814 | 23 | |
sgroeger@3814 | 24 | /* |
sgroeger@3814 | 25 | * @test |
sgroeger@3814 | 26 | * @bug 8218152 |
sgroeger@3814 | 27 | * @summary A bad annotation processor class file should fail with an error |
sgroeger@3814 | 28 | * @author Steven Groeger |
sgroeger@3814 | 29 | * |
sgroeger@3814 | 30 | * @library /tools/javac/lib |
sgroeger@3814 | 31 | * @build ToolBox |
sgroeger@3814 | 32 | * @run main MalformedAnnotationProcessorTests |
sgroeger@3814 | 33 | */ |
sgroeger@3814 | 34 | |
sgroeger@3814 | 35 | import java.io.*; |
sgroeger@3814 | 36 | import java.util.*; |
sgroeger@3814 | 37 | import java.io.RandomAccessFile; |
sgroeger@3814 | 38 | import java.nio.ByteBuffer; |
sgroeger@3814 | 39 | import java.nio.channels.FileChannel; |
sgroeger@3814 | 40 | import java.nio.file.Files; |
sgroeger@3814 | 41 | import java.nio.file.Path; |
sgroeger@3814 | 42 | import java.nio.file.Paths; |
sgroeger@3814 | 43 | import java.util.List; |
sgroeger@3814 | 44 | import javax.annotation.processing.Processor; |
sgroeger@3814 | 45 | |
sgroeger@3814 | 46 | public class MalformedAnnotationProcessorTests { |
sgroeger@3814 | 47 | public static void main(String... args) throws Exception { |
sgroeger@3814 | 48 | new MalformedAnnotationProcessorTests().run(); |
sgroeger@3814 | 49 | } |
sgroeger@3814 | 50 | |
sgroeger@3814 | 51 | void run() throws Exception { |
sgroeger@3814 | 52 | testBadAnnotationProcessor(Paths.get(".")); |
sgroeger@3814 | 53 | testMissingAnnotationProcessor(Paths.get(".")); |
sgroeger@3814 | 54 | testWrongClassFileVersion(Paths.get(".")); |
sgroeger@3814 | 55 | } |
sgroeger@3814 | 56 | |
sgroeger@3814 | 57 | public void testBadAnnotationProcessor(Path base) throws Exception { |
sgroeger@3814 | 58 | Path apDir = base.resolve("annoprocessor"); |
sgroeger@3814 | 59 | ToolBox.writeFile(apDir.resolve("META-INF").resolve("services") |
sgroeger@3814 | 60 | .resolve(Processor.class.getCanonicalName()), "BadAnnoProcessor"); |
sgroeger@3814 | 61 | ToolBox.writeFile(apDir.resolve("BadAnnoProcessor.class"), "badannoprocessor"); |
sgroeger@3814 | 62 | |
sgroeger@3814 | 63 | Path classes = base.resolve("classes"); |
sgroeger@3814 | 64 | Files.createDirectories(classes); |
sgroeger@3814 | 65 | |
sgroeger@3814 | 66 | List<String> actualErrors = new ArrayList<>(); |
sgroeger@3814 | 67 | ToolBox.JavaToolArgs args = new ToolBox.JavaToolArgs(); |
sgroeger@3814 | 68 | args.setSources("package test; public class Test {}") |
sgroeger@3814 | 69 | .appendArgs("-XDrawDiagnostics", |
sgroeger@3814 | 70 | "-d", classes.toString(), |
sgroeger@3814 | 71 | "-classpath", "", |
sgroeger@3814 | 72 | "-processorpath", apDir.toString()) |
sgroeger@3814 | 73 | .set(ToolBox.Expect.FAIL) |
sgroeger@3814 | 74 | .setErrOutput(actualErrors); |
sgroeger@3814 | 75 | ToolBox.javac(args); |
sgroeger@3814 | 76 | |
sgroeger@3814 | 77 | System.out.println(actualErrors.get(0)); |
sgroeger@3814 | 78 | if (!actualErrors.get(0).contains("- compiler.err.proc.cant.load.class: " + |
sgroeger@3814 | 79 | "Incompatible magic value")) { |
sgroeger@3814 | 80 | throw new AssertionError("Unexpected errors reported: " + actualErrors); |
sgroeger@3814 | 81 | } |
sgroeger@3814 | 82 | } |
sgroeger@3814 | 83 | |
sgroeger@3814 | 84 | public void testMissingAnnotationProcessor(Path base) throws Exception { |
sgroeger@3814 | 85 | Path apDir = base.resolve("annoprocessor"); |
sgroeger@3814 | 86 | ToolBox.writeFile(apDir.resolve("META-INF").resolve("services").resolve(Processor.class.getCanonicalName()), |
sgroeger@3814 | 87 | "MissingAnnoProcessor"); |
sgroeger@3814 | 88 | |
sgroeger@3814 | 89 | Path classes = base.resolve("classes"); |
sgroeger@3814 | 90 | Files.createDirectories(classes); |
sgroeger@3814 | 91 | |
sgroeger@3814 | 92 | List<String> actualErrors = new ArrayList<>(); |
sgroeger@3814 | 93 | ToolBox.JavaToolArgs args = new ToolBox.JavaToolArgs(); |
sgroeger@3814 | 94 | args.setSources("package test; public class Test {}") |
sgroeger@3814 | 95 | .appendArgs("-XDrawDiagnostics", |
sgroeger@3814 | 96 | "-d", classes.toString(), |
sgroeger@3814 | 97 | "-classpath", "", |
sgroeger@3814 | 98 | "-processorpath", apDir.toString()) |
sgroeger@3814 | 99 | .set(ToolBox.Expect.FAIL) |
sgroeger@3814 | 100 | .setErrOutput(actualErrors); |
sgroeger@3814 | 101 | ToolBox.javac(args); |
sgroeger@3814 | 102 | |
sgroeger@3814 | 103 | if (!actualErrors.get(0).contains("- compiler.err.proc.bad.config.file: " + |
sgroeger@3814 | 104 | "javax.annotation.processing.Processor: Provider MissingAnnoProcessor not found")) { |
sgroeger@3814 | 105 | throw new AssertionError("Unexpected errors reported: " + actualErrors); |
sgroeger@3814 | 106 | } |
sgroeger@3814 | 107 | } |
sgroeger@3814 | 108 | |
sgroeger@3814 | 109 | public void testWrongClassFileVersion(Path base) throws Exception { |
sgroeger@3814 | 110 | Path apDir = base.resolve("annoprocessor"); |
sgroeger@3814 | 111 | ToolBox.writeFile(apDir.resolve("META-INF").resolve("services").resolve(Processor.class.getCanonicalName()), |
sgroeger@3814 | 112 | "WrongClassFileVersion"); |
sgroeger@3814 | 113 | |
sgroeger@3814 | 114 | ToolBox.JavaToolArgs args = new ToolBox.JavaToolArgs(); |
sgroeger@3814 | 115 | args.setSources("class WrongClassFileVersion {}") |
sgroeger@3814 | 116 | .appendArgs("-d", apDir.toString()) |
sgroeger@3814 | 117 | .set(ToolBox.Expect.SUCCESS); |
sgroeger@3814 | 118 | ToolBox.javac(args); |
sgroeger@3814 | 119 | |
sgroeger@3814 | 120 | increaseMajor(apDir.resolve("WrongClassFileVersion.class"), 1); |
sgroeger@3814 | 121 | |
sgroeger@3814 | 122 | Path classes = base.resolve("classes"); |
sgroeger@3814 | 123 | Files.createDirectories(classes); |
sgroeger@3814 | 124 | |
sgroeger@3814 | 125 | List<String> actualErrors = new ArrayList<>(); |
sgroeger@3814 | 126 | args = new ToolBox.JavaToolArgs(); |
sgroeger@3814 | 127 | args.setSources("package test; public class Test {}") |
sgroeger@3814 | 128 | .appendArgs("-XDrawDiagnostics", |
sgroeger@3814 | 129 | "-d", classes.toString(), |
sgroeger@3814 | 130 | "-classpath", "", |
sgroeger@3814 | 131 | "-processorpath", apDir.toString()) |
sgroeger@3814 | 132 | .set(ToolBox.Expect.FAIL) |
sgroeger@3814 | 133 | .setErrOutput(actualErrors); |
sgroeger@3814 | 134 | ToolBox.javac(args); |
sgroeger@3814 | 135 | |
sgroeger@3814 | 136 | if (!actualErrors.get(0).contains("- compiler.err.proc.cant.load.class: " + |
sgroeger@3814 | 137 | "WrongClassFileVersion has been compiled by a more recent version")) { |
sgroeger@3814 | 138 | throw new AssertionError("Unexpected errors reported: " + actualErrors); |
sgroeger@3814 | 139 | } |
sgroeger@3814 | 140 | } |
sgroeger@3814 | 141 | |
sgroeger@3814 | 142 | // Increase class file cfile's major version by delta |
sgroeger@3814 | 143 | // (note: based on test/langtools/tools/javac/6330997/T6330997.java) |
sgroeger@3814 | 144 | static void increaseMajor(Path cfile, int delta) { |
sgroeger@3814 | 145 | try (RandomAccessFile cls = |
sgroeger@3814 | 146 | new RandomAccessFile(cfile.toFile(), "rw"); |
sgroeger@3814 | 147 | FileChannel fc = cls.getChannel()) { |
sgroeger@3814 | 148 | ByteBuffer rbuf = ByteBuffer.allocate(2); |
sgroeger@3814 | 149 | fc.read(rbuf, 6); |
sgroeger@3814 | 150 | ByteBuffer wbuf = ByteBuffer.allocate(2); |
sgroeger@3814 | 151 | wbuf.putShort(0, (short)(rbuf.getShort(0) + delta)); |
sgroeger@3814 | 152 | fc.write(wbuf, 6); |
sgroeger@3814 | 153 | fc.force(false); |
sgroeger@3814 | 154 | } catch (Exception e){ |
sgroeger@3814 | 155 | throw new RuntimeException("Failed: unexpected exception"); |
sgroeger@3814 | 156 | } |
sgroeger@3814 | 157 | } |
sgroeger@3814 | 158 | } |