Fri, 10 Jan 2014 12:47:15 +0100
8028389: NullPointerException compiling annotation values that have bodies
Summary: Made sure anonymous class declarations inside class- and package-level annotations are properly entered.
Reviewed-by: jfranck
1 /*
2 * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package anttasks;
28 import genstubs.GenStubs;
30 import java.io.*;
31 import java.util.*;
33 import org.apache.tools.ant.BuildException;
34 import org.apache.tools.ant.DirectoryScanner;
35 import org.apache.tools.ant.taskdefs.MatchingTask;
36 import org.apache.tools.ant.types.Path;
37 import org.apache.tools.ant.types.Reference;
39 /**
40 * Files are specified with an implicit fileset, using srcdir as a base directory.
41 * The set of files to be included is specified with an includes attribute or
42 * nested <includes> set. However, unlike a normal fileset, an empty includes attribute
43 * means "no files" instead of "all files". The Ant task also accepts "fork=true" and
44 * classpath attribute or nested <classpath> element to run GenStubs in a separate VM
45 * with the specified path. This is likely necessary if a JDK 7 parser is required to read the
46 * JDK 7 input files.
47 */
48 public class GenStubsTask extends MatchingTask {
49 private File srcDir;
50 private File destDir;
51 private boolean fork;
52 private Path classpath;
53 private String includes;
55 public void setSrcDir(File dir) {
56 this.srcDir = dir;
57 }
59 public void setDestDir(File dir) {
60 this.destDir = dir;
61 }
63 public void setFork(boolean v) {
64 this.fork = v;
65 }
67 public void setClasspath(Path cp) {
68 if (classpath == null)
69 classpath = cp;
70 else
71 classpath.append(cp);
72 }
74 public Path createClasspath() {
75 if (classpath == null) {
76 classpath = new Path(getProject());
77 }
78 return classpath.createPath();
79 }
81 public void setClasspathRef(Reference r) {
82 createClasspath().setRefid(r);
83 }
85 public void setIncludes(String includes) {
86 super.setIncludes(includes);
87 this.includes = includes;
88 }
90 @Override
91 public void execute() {
92 if (includes != null && includes.trim().isEmpty())
93 return;
95 DirectoryScanner s = getDirectoryScanner(srcDir);
96 String[] files = s.getIncludedFiles();
97 // System.err.println("Ant.execute: srcDir " + srcDir);
98 // System.err.println("Ant.execute: destDir " + destDir);
99 // System.err.println("Ant.execute: files " + Arrays.asList(files));
101 files = filter(srcDir, destDir, files);
102 if (files.length == 0)
103 return;
104 System.out.println("Generating " + files.length + " stub files to " + destDir);
106 List<String> classNames = new ArrayList<String>();
107 for (String file: files) {
108 classNames.add(file.replaceAll(".java$", "").replace('/', '.'));
109 }
111 if (!fork) {
112 GenStubs m = new GenStubs();
113 boolean ok = m.run(srcDir.getPath(), destDir, classNames);
114 if (!ok)
115 throw new BuildException("genstubs failed");
116 } else {
117 List<String> cmd = new ArrayList<String>();
118 String java_home = System.getProperty("java.home");
119 cmd.add(new File(new File(java_home, "bin"), "java").getPath());
120 if (classpath != null)
121 cmd.add("-Xbootclasspath/p:" + classpath);
122 cmd.add(GenStubs.class.getName());
123 cmd.add("-sourcepath");
124 cmd.add(srcDir.getPath());
125 cmd.add("-s");
126 cmd.add(destDir.getPath());
127 cmd.addAll(classNames);
128 //System.err.println("GenStubs exec " + cmd);
129 ProcessBuilder pb = new ProcessBuilder(cmd);
130 pb.redirectErrorStream(true);
131 try {
132 Process p = pb.start();
133 BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
134 try {
135 String line;
136 while ((line = in.readLine()) != null)
137 System.out.println(line);
138 } finally {
139 in.close();
140 }
141 int rc = p.waitFor();
142 if (rc != 0)
143 throw new BuildException("genstubs failed");
144 } catch (IOException e) {
145 throw new BuildException("genstubs failed", e);
146 } catch (InterruptedException e) {
147 throw new BuildException("genstubs failed", e);
148 }
149 }
150 }
152 String[] filter(File srcDir, File destDir, String[] files) {
153 List<String> results = new ArrayList<String>();
154 for (String f: files) {
155 long srcTime = new File(srcDir, f).lastModified();
156 long destTime = new File(destDir, f).lastModified();
157 if (srcTime > destTime)
158 results.add(f);
159 }
160 return results.toArray(new String[results.size()]);
161 }
162 }