feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,384 @@
/*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javah;
import java.io.UnsupportedEncodingException;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.FileObject;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;
/**
* An abstraction for generating support files required by native methods.
* Subclasses are for specific native interfaces. At the time of its
* original writing, this interface is rich enough to support JNI and the
* old 1.0-style native method interface.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*
* @author Sucheta Dambalkar(Revised)
*/
public abstract class Gen {
protected String lineSep = System.getProperty("line.separator");
protected ProcessingEnvironment processingEnvironment;
protected Types types;
protected Elements elems;
protected Mangle mangler;
protected Util util;
protected Gen(Util util) {
this.util = util;
}
/*
* List of classes for which we must generate output.
*/
protected Set<TypeElement> classes;
static private final boolean isWindows =
System.getProperty("os.name").startsWith("Windows");
/**
* Override this abstract method, generating content for the named
* class into the outputstream.
*/
protected abstract void write(OutputStream o, TypeElement clazz) throws Util.Exit;
/**
* Override this method to provide a list of #include statements
* required by the native interface.
*/
protected abstract String getIncludes();
/*
* Output location.
*/
protected JavaFileManager fileManager;
protected JavaFileObject outFile;
public void setFileManager(JavaFileManager fm) {
fileManager = fm;
}
public void setOutFile(JavaFileObject outFile) {
this.outFile = outFile;
}
public void setClasses(Set<TypeElement> classes) {
this.classes = classes;
}
void setProcessingEnvironment(ProcessingEnvironment pEnv) {
processingEnvironment = pEnv;
elems = pEnv.getElementUtils();
types = pEnv.getTypeUtils();
mangler = new Mangle(elems, types);
}
/*
* Smartness with generated files.
*/
protected boolean force = false;
public void setForce(boolean state) {
force = state;
}
/**
* We explicitly need to write ASCII files because that is what C
* compilers understand.
*/
protected PrintWriter wrapWriter(OutputStream o) throws Util.Exit {
try {
return new PrintWriter(new OutputStreamWriter(o, "ISO8859_1"), true);
} catch (UnsupportedEncodingException use) {
util.bug("encoding.iso8859_1.not.found");
return null; /* dead code */
}
}
/**
* After initializing state of an instance, use this method to start
* processing.
*
* Buffer size chosen as an approximation from a single sampling of:
* expr `du -sk` / `ls *.h | wc -l`
*/
public void run() throws IOException, ClassNotFoundException, Util.Exit {
int i = 0;
if (outFile != null) {
/* Everything goes to one big file... */
ByteArrayOutputStream bout = new ByteArrayOutputStream(8192);
writeFileTop(bout); /* only once */
for (TypeElement t: classes) {
write(bout, t);
}
writeIfChanged(bout.toByteArray(), outFile);
} else {
/* Each class goes to its own file... */
for (TypeElement t: classes) {
ByteArrayOutputStream bout = new ByteArrayOutputStream(8192);
writeFileTop(bout);
write(bout, t);
writeIfChanged(bout.toByteArray(), getFileObject(t.getQualifiedName()));
}
}
}
/*
* Write the contents of byte[] b to a file named file. Writing
* is done if either the file doesn't exist or if the contents are
* different.
*/
private void writeIfChanged(byte[] b, FileObject file) throws IOException {
boolean mustWrite = false;
String event = "[No need to update file ";
if (force) {
mustWrite = true;
event = "[Forcefully writing file ";
} else {
InputStream in;
byte[] a;
try {
// regrettably, there's no API to get the length in bytes
// for a FileObject, so we can't short-circuit reading the
// file here
in = file.openInputStream();
a = readBytes(in);
if (!Arrays.equals(a, b)) {
mustWrite = true;
event = "[Overwriting file ";
}
} catch (FileNotFoundException e) {
mustWrite = true;
event = "[Creating file ";
}
}
if (util.verbose)
util.log(event + file + "]");
if (mustWrite) {
OutputStream out = file.openOutputStream();
out.write(b); /* No buffering, just one big write! */
out.close();
}
}
protected byte[] readBytes(InputStream in) throws IOException {
try {
byte[] array = new byte[in.available() + 1];
int offset = 0;
int n;
while ((n = in.read(array, offset, array.length - offset)) != -1) {
offset += n;
if (offset == array.length)
array = Arrays.copyOf(array, array.length * 2);
}
return Arrays.copyOf(array, offset);
} finally {
in.close();
}
}
protected String defineForStatic(TypeElement c, VariableElement f)
throws Util.Exit {
CharSequence cnamedoc = c.getQualifiedName();
CharSequence fnamedoc = f.getSimpleName();
String cname = mangler.mangle(cnamedoc, Mangle.Type.CLASS);
String fname = mangler.mangle(fnamedoc, Mangle.Type.FIELDSTUB);
if (!f.getModifiers().contains(Modifier.STATIC))
util.bug("tried.to.define.non.static");
if (f.getModifiers().contains(Modifier.FINAL)) {
Object value = null;
value = f.getConstantValue();
if (value != null) { /* so it is a ConstantExpression */
String constString = null;
if ((value instanceof Integer)
|| (value instanceof Byte)
|| (value instanceof Short)) {
/* covers byte, short, int */
constString = value.toString() + "L";
} else if (value instanceof Boolean) {
constString = ((Boolean) value) ? "1L" : "0L";
} else if (value instanceof Character) {
Character ch = (Character) value;
constString = String.valueOf(((int) ch) & 0xffff) + "L";
} else if (value instanceof Long) {
// Visual C++ supports the i64 suffix, not LL.
if (isWindows)
constString = value.toString() + "i64";
else
constString = value.toString() + "LL";
} else if (value instanceof Float) {
/* bug for bug */
float fv = ((Float)value).floatValue();
if (Float.isInfinite(fv))
constString = ((fv < 0) ? "-" : "") + "Inff";
else
constString = value.toString() + "f";
} else if (value instanceof Double) {
/* bug for bug */
double d = ((Double)value).doubleValue();
if (Double.isInfinite(d))
constString = ((d < 0) ? "-" : "") + "InfD";
else
constString = value.toString();
}
if (constString != null) {
StringBuilder s = new StringBuilder("#undef ");
s.append(cname); s.append("_"); s.append(fname); s.append(lineSep);
s.append("#define "); s.append(cname); s.append("_");
s.append(fname); s.append(" "); s.append(constString);
return s.toString();
}
}
}
return null;
}
/*
* Deal with the C pre-processor.
*/
protected String cppGuardBegin() {
return "#ifdef __cplusplus" + lineSep + "extern \"C\" {" + lineSep + "#endif";
}
protected String cppGuardEnd() {
return "#ifdef __cplusplus" + lineSep + "}" + lineSep + "#endif";
}
protected String guardBegin(String cname) {
return "/* Header for class " + cname + " */" + lineSep + lineSep +
"#ifndef _Included_" + cname + lineSep +
"#define _Included_" + cname;
}
protected String guardEnd(String cname) {
return "#endif";
}
/*
* File name and file preamble related operations.
*/
protected void writeFileTop(OutputStream o) throws Util.Exit {
PrintWriter pw = wrapWriter(o);
pw.println("/* DO NOT EDIT THIS FILE - it is machine generated */" + lineSep +
getIncludes());
}
protected String baseFileName(CharSequence className) {
return mangler.mangle(className, Mangle.Type.CLASS);
}
protected FileObject getFileObject(CharSequence className) throws IOException {
String name = baseFileName(className) + getFileSuffix();
return fileManager.getFileForOutput(StandardLocation.SOURCE_OUTPUT, "", name, null);
}
protected String getFileSuffix() {
return ".h";
}
/**
* Including super classes' fields.
*/
List<VariableElement> getAllFields(TypeElement subclazz) {
List<VariableElement> fields = new ArrayList<VariableElement>();
TypeElement cd = null;
Stack<TypeElement> s = new Stack<TypeElement>();
cd = subclazz;
while (true) {
s.push(cd);
TypeElement c = (TypeElement) (types.asElement(cd.getSuperclass()));
if (c == null)
break;
cd = c;
}
while (!s.empty()) {
cd = s.pop();
fields.addAll(ElementFilter.fieldsIn(cd.getEnclosedElements()));
}
return fields;
}
// c.f. MethodDoc.signature
String signature(ExecutableElement e) {
StringBuilder sb = new StringBuilder("(");
String sep = "";
for (VariableElement p: e.getParameters()) {
sb.append(sep);
sb.append(types.erasure(p.asType()).toString());
sep = ",";
}
sb.append(")");
return sb.toString();
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javah;
/**
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class InternalError extends Error {
private static final long serialVersionUID = 8411861562497165022L;
InternalError(String msg, Throwable cause) {
super("Internal error: " + msg);
initCause(cause);
}
}

View File

@@ -0,0 +1,185 @@
/*
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javah;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementFilter;
/**
* Header file generator for JNI.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*
* @author Sucheta Dambalkar(Revised)
*/
public class JNI extends Gen {
JNI(Util util) {
super(util);
}
public String getIncludes() {
return "#include <jni.h>";
}
public void write(OutputStream o, TypeElement clazz) throws Util.Exit {
try {
String cname = mangler.mangle(clazz.getQualifiedName(), Mangle.Type.CLASS);
PrintWriter pw = wrapWriter(o);
pw.println(guardBegin(cname));
pw.println(cppGuardBegin());
/* Write statics. */
List<VariableElement> classfields = getAllFields(clazz);
for (VariableElement v: classfields) {
if (!v.getModifiers().contains(Modifier.STATIC))
continue;
String s = null;
s = defineForStatic(clazz, v);
if (s != null) {
pw.println(s);
}
}
/* Write methods. */
List<ExecutableElement> classmethods = ElementFilter.methodsIn(clazz.getEnclosedElements());
for (ExecutableElement md: classmethods) {
if(md.getModifiers().contains(Modifier.NATIVE)){
TypeMirror mtr = types.erasure(md.getReturnType());
String sig = signature(md);
TypeSignature newtypesig = new TypeSignature(elems);
CharSequence methodName = md.getSimpleName();
boolean longName = false;
for (ExecutableElement md2: classmethods) {
if ((md2 != md)
&& (methodName.equals(md2.getSimpleName()))
&& (md2.getModifiers().contains(Modifier.NATIVE)))
longName = true;
}
pw.println("/*");
pw.println(" * Class: " + cname);
pw.println(" * Method: " +
mangler.mangle(methodName, Mangle.Type.FIELDSTUB));
pw.println(" * Signature: " + newtypesig.getTypeSignature(sig, mtr));
pw.println(" */");
pw.println("JNIEXPORT " + jniType(mtr) +
" JNICALL " +
mangler.mangleMethod(md, clazz,
(longName) ?
Mangle.Type.METHOD_JNI_LONG :
Mangle.Type.METHOD_JNI_SHORT));
pw.print(" (JNIEnv *, ");
List<? extends VariableElement> paramargs = md.getParameters();
List<TypeMirror> args = new ArrayList<TypeMirror>();
for (VariableElement p: paramargs) {
args.add(types.erasure(p.asType()));
}
if (md.getModifiers().contains(Modifier.STATIC))
pw.print("jclass");
else
pw.print("jobject");
for (TypeMirror arg: args) {
pw.print(", ");
pw.print(jniType(arg));
}
pw.println(");" + lineSep);
}
}
pw.println(cppGuardEnd());
pw.println(guardEnd(cname));
} catch (TypeSignature.SignatureException e) {
util.error("jni.sigerror", e.getMessage());
}
}
protected final String jniType(TypeMirror t) throws Util.Exit {
TypeElement throwable = elems.getTypeElement("java.lang.Throwable");
TypeElement jClass = elems.getTypeElement("java.lang.Class");
TypeElement jString = elems.getTypeElement("java.lang.String");
Element tclassDoc = types.asElement(t);
switch (t.getKind()) {
case ARRAY: {
TypeMirror ct = ((ArrayType) t).getComponentType();
switch (ct.getKind()) {
case BOOLEAN: return "jbooleanArray";
case BYTE: return "jbyteArray";
case CHAR: return "jcharArray";
case SHORT: return "jshortArray";
case INT: return "jintArray";
case LONG: return "jlongArray";
case FLOAT: return "jfloatArray";
case DOUBLE: return "jdoubleArray";
case ARRAY:
case DECLARED: return "jobjectArray";
default: throw new Error(ct.toString());
}
}
case VOID: return "void";
case BOOLEAN: return "jboolean";
case BYTE: return "jbyte";
case CHAR: return "jchar";
case SHORT: return "jshort";
case INT: return "jint";
case LONG: return "jlong";
case FLOAT: return "jfloat";
case DOUBLE: return "jdouble";
case DECLARED: {
if (tclassDoc.equals(jString))
return "jstring";
else if (types.isAssignable(t, throwable.asType()))
return "jthrowable";
else if (types.isAssignable(t, jClass.asType()))
return "jclass";
else
return "jobject";
}
}
util.bug("jni.unknown.type");
return null; /* dead code. */
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javah;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.util.Context;
/**
* javah's implementation of JavaFileManager.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
class JavahFileManager extends JavacFileManager {
private JavahFileManager(Context context, Charset charset) {
super(context, true, charset);
setSymbolFileEnabled(false);
}
static JavahFileManager create(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) {
Context javac_context = new Context();
if (dl != null)
javac_context.put(DiagnosticListener.class, dl);
javac_context.put(com.sun.tools.javac.util.Log.outKey, log);
return new JavahFileManager(javac_context, null);
}
}

View File

@@ -0,0 +1,759 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javah;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVisitor;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.SimpleTypeVisitor8;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import static javax.tools.Diagnostic.Kind.*;
import com.sun.tools.javac.code.Symbol.CompletionFailure;
import com.sun.tools.javac.main.CommandLine;
/**
* Javah generates support files for native methods.
* Parse commandline options and invokes javadoc to execute those commands.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*
* @author Sucheta Dambalkar
* @author Jonathan Gibbons
*/
public class JavahTask implements NativeHeaderTool.NativeHeaderTask {
public class BadArgs extends Exception {
private static final long serialVersionUID = 1479361270874789045L;
BadArgs(String key, Object... args) {
super(JavahTask.this.getMessage(key, args));
this.key = key;
this.args = args;
}
BadArgs showUsage(boolean b) {
showUsage = b;
return this;
}
final String key;
final Object[] args;
boolean showUsage;
}
static abstract class Option {
Option(boolean hasArg, String... aliases) {
this.hasArg = hasArg;
this.aliases = aliases;
}
boolean isHidden() {
return false;
}
boolean matches(String opt) {
for (String a: aliases) {
if (a.equals(opt))
return true;
}
return false;
}
boolean ignoreRest() {
return false;
}
abstract void process(JavahTask task, String opt, String arg) throws BadArgs;
final boolean hasArg;
final String[] aliases;
}
static abstract class HiddenOption extends Option {
HiddenOption(boolean hasArg, String... aliases) {
super(hasArg, aliases);
}
@Override
boolean isHidden() {
return true;
}
}
static final Option[] recognizedOptions = {
new Option(true, "-o") {
void process(JavahTask task, String opt, String arg) {
task.ofile = new File(arg);
}
},
new Option(true, "-d") {
void process(JavahTask task, String opt, String arg) {
task.odir = new File(arg);
}
},
new HiddenOption(true, "-td") {
void process(JavahTask task, String opt, String arg) {
// ignored; for backwards compatibility
}
},
new HiddenOption(false, "-stubs") {
void process(JavahTask task, String opt, String arg) {
// ignored; for backwards compatibility
}
},
new Option(false, "-v", "-verbose") {
void process(JavahTask task, String opt, String arg) {
task.verbose = true;
}
},
new Option(false, "-h", "-help", "--help", "-?") {
void process(JavahTask task, String opt, String arg) {
task.help = true;
}
},
new HiddenOption(false, "-trace") {
void process(JavahTask task, String opt, String arg) {
task.trace = true;
}
},
new Option(false, "-version") {
void process(JavahTask task, String opt, String arg) {
task.version = true;
}
},
new HiddenOption(false, "-fullversion") {
void process(JavahTask task, String opt, String arg) {
task.fullVersion = true;
}
},
new Option(false, "-jni") {
void process(JavahTask task, String opt, String arg) {
task.jni = true;
}
},
new Option(false, "-force") {
void process(JavahTask task, String opt, String arg) {
task.force = true;
}
},
new HiddenOption(false, "-Xnew") {
void process(JavahTask task, String opt, String arg) {
// we're already using the new javah
}
},
new HiddenOption(false, "-llni", "-Xllni") {
void process(JavahTask task, String opt, String arg) {
task.llni = true;
}
},
new HiddenOption(false, "-llnidouble") {
void process(JavahTask task, String opt, String arg) {
task.llni = true;
task.doubleAlign = true;
}
},
new HiddenOption(false) {
boolean matches(String opt) {
return opt.startsWith("-XD");
}
void process(JavahTask task, String opt, String arg) {
task.javac_extras.add(opt);
}
},
};
JavahTask() {
}
JavahTask(Writer out,
JavaFileManager fileManager,
DiagnosticListener<? super JavaFileObject> diagnosticListener,
Iterable<String> options,
Iterable<String> classes) {
this();
this.log = getPrintWriterForWriter(out);
this.fileManager = fileManager;
this.diagnosticListener = diagnosticListener;
try {
handleOptions(options, false);
} catch (BadArgs e) {
throw new IllegalArgumentException(e.getMessage());
}
this.classes = new ArrayList<String>();
if (classes != null) {
for (String classname: classes) {
classname.getClass(); // null-check
this.classes.add(classname);
}
}
}
public void setLocale(Locale locale) {
if (locale == null)
locale = Locale.getDefault();
task_locale = locale;
}
public void setLog(PrintWriter log) {
this.log = log;
}
public void setLog(OutputStream s) {
setLog(getPrintWriterForStream(s));
}
static PrintWriter getPrintWriterForStream(OutputStream s) {
return new PrintWriter(s, true);
}
static PrintWriter getPrintWriterForWriter(Writer w) {
if (w == null)
return getPrintWriterForStream(null);
else if (w instanceof PrintWriter)
return (PrintWriter) w;
else
return new PrintWriter(w, true);
}
public void setDiagnosticListener(DiagnosticListener<? super JavaFileObject> dl) {
diagnosticListener = dl;
}
public void setDiagnosticListener(OutputStream s) {
setDiagnosticListener(getDiagnosticListenerForStream(s));
}
private DiagnosticListener<JavaFileObject> getDiagnosticListenerForStream(OutputStream s) {
return getDiagnosticListenerForWriter(getPrintWriterForStream(s));
}
private DiagnosticListener<JavaFileObject> getDiagnosticListenerForWriter(Writer w) {
final PrintWriter pw = getPrintWriterForWriter(w);
return new DiagnosticListener<JavaFileObject> () {
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
pw.print(getMessage("err.prefix"));
pw.print(" ");
}
pw.println(diagnostic.getMessage(null));
}
};
}
int run(String[] args) {
try {
handleOptions(args);
boolean ok = run();
return ok ? 0 : 1;
} catch (BadArgs e) {
diagnosticListener.report(createDiagnostic(e.key, e.args));
return 1;
} catch (InternalError e) {
diagnosticListener.report(createDiagnostic("err.internal.error", e.getMessage()));
return 1;
} catch (Util.Exit e) {
return e.exitValue;
} finally {
log.flush();
}
}
public void handleOptions(String[] args) throws BadArgs {
handleOptions(Arrays.asList(args), true);
}
private void handleOptions(Iterable<String> args, boolean allowClasses) throws BadArgs {
if (log == null) {
log = getPrintWriterForStream(System.out);
if (diagnosticListener == null)
diagnosticListener = getDiagnosticListenerForStream(System.err);
} else {
if (diagnosticListener == null)
diagnosticListener = getDiagnosticListenerForWriter(log);
}
if (fileManager == null)
fileManager = getDefaultFileManager(diagnosticListener, log);
Iterator<String> iter = expandAtArgs(args).iterator();
noArgs = !iter.hasNext();
while (iter.hasNext()) {
String arg = iter.next();
if (arg.startsWith("-"))
handleOption(arg, iter);
else if (allowClasses) {
if (classes == null)
classes = new ArrayList<String>();
classes.add(arg);
while (iter.hasNext())
classes.add(iter.next());
} else
throw new BadArgs("err.unknown.option", arg).showUsage(true);
}
if ((classes == null || classes.size() == 0) &&
!(noArgs || help || version || fullVersion)) {
throw new BadArgs("err.no.classes.specified");
}
if (jni && llni)
throw new BadArgs("jni.llni.mixed");
if (odir != null && ofile != null)
throw new BadArgs("dir.file.mixed");
}
private void handleOption(String name, Iterator<String> rest) throws BadArgs {
for (Option o: recognizedOptions) {
if (o.matches(name)) {
if (o.hasArg) {
if (rest.hasNext())
o.process(this, name, rest.next());
else
throw new BadArgs("err.missing.arg", name).showUsage(true);
} else
o.process(this, name, null);
if (o.ignoreRest()) {
while (rest.hasNext())
rest.next();
}
return;
}
}
if (fileManager.handleOption(name, rest))
return;
throw new BadArgs("err.unknown.option", name).showUsage(true);
}
private Iterable<String> expandAtArgs(Iterable<String> args) throws BadArgs {
try {
List<String> l = new ArrayList<String>();
for (String arg: args) l.add(arg);
return Arrays.asList(CommandLine.parse(l.toArray(new String[l.size()])));
} catch (FileNotFoundException e) {
throw new BadArgs("at.args.file.not.found", e.getLocalizedMessage());
} catch (IOException e) {
throw new BadArgs("at.args.io.exception", e.getLocalizedMessage());
}
}
public Boolean call() {
return run();
}
public boolean run() throws Util.Exit {
Util util = new Util(log, diagnosticListener);
if (noArgs || help) {
showHelp();
return help; // treat noArgs as an error for purposes of exit code
}
if (version || fullVersion) {
showVersion(fullVersion);
return true;
}
util.verbose = verbose;
Gen g;
if (llni)
g = new LLNI(doubleAlign, util);
else {
// if (stubs)
// throw new BadArgs("jni.no.stubs");
g = new JNI(util);
}
if (ofile != null) {
if (!(fileManager instanceof StandardJavaFileManager)) {
diagnosticListener.report(createDiagnostic("err.cant.use.option.for.fm", "-o"));
return false;
}
Iterable<? extends JavaFileObject> iter =
((StandardJavaFileManager) fileManager).getJavaFileObjectsFromFiles(Collections.singleton(ofile));
JavaFileObject fo = iter.iterator().next();
g.setOutFile(fo);
} else {
if (odir != null) {
if (!(fileManager instanceof StandardJavaFileManager)) {
diagnosticListener.report(createDiagnostic("err.cant.use.option.for.fm", "-d"));
return false;
}
if (!odir.exists())
if (!odir.mkdirs())
util.error("cant.create.dir", odir.toString());
try {
((StandardJavaFileManager) fileManager).setLocation(StandardLocation.CLASS_OUTPUT, Collections.singleton(odir));
} catch (IOException e) {
Object msg = e.getLocalizedMessage();
if (msg == null) {
msg = e;
}
diagnosticListener.report(createDiagnostic("err.ioerror", odir, msg));
return false;
}
}
g.setFileManager(fileManager);
}
/*
* Force set to false will turn off smarts about checking file
* content before writing.
*/
g.setForce(force);
if (fileManager instanceof JavahFileManager)
((JavahFileManager) fileManager).setSymbolFileEnabled(false);
JavaCompiler c = ToolProvider.getSystemJavaCompiler();
List<String> opts = new ArrayList<String>();
opts.add("-proc:only");
opts.addAll(javac_extras);
CompilationTask t = c.getTask(log, fileManager, diagnosticListener, opts, classes, null);
JavahProcessor p = new JavahProcessor(g);
t.setProcessors(Collections.singleton(p));
boolean ok = t.call();
if (p.exit != null)
throw new Util.Exit(p.exit);
return ok;
}
private List<File> pathToFiles(String path) {
List<File> files = new ArrayList<File>();
for (String f: path.split(File.pathSeparator)) {
if (f.length() > 0)
files.add(new File(f));
}
return files;
}
static StandardJavaFileManager getDefaultFileManager(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) {
return JavahFileManager.create(dl, log);
}
private void showHelp() {
log.println(getMessage("main.usage", progname));
for (Option o: recognizedOptions) {
if (o.isHidden())
continue;
String name = o.aliases[0].substring(1); // there must always be at least one name
log.println(getMessage("main.opt." + name));
}
String[] fmOptions = { "-classpath", "-cp", "-bootclasspath" };
for (String o: fmOptions) {
if (fileManager.isSupportedOption(o) == -1)
continue;
String name = o.substring(1);
log.println(getMessage("main.opt." + name));
}
log.println(getMessage("main.usage.foot"));
}
private void showVersion(boolean full) {
log.println(version(full));
}
private static final String versionRBName = "com.sun.tools.javah.resources.version";
private static ResourceBundle versionRB;
private String version(boolean full) {
String msgKey = (full ? "javah.fullVersion" : "javah.version");
String versionKey = (full ? "full" : "release");
// versionKey=product: mm.nn.oo[-milestone]
// versionKey=full: mm.mm.oo[-milestone]-build
if (versionRB == null) {
try {
versionRB = ResourceBundle.getBundle(versionRBName);
} catch (MissingResourceException e) {
return getMessage("version.resource.missing", System.getProperty("java.version"));
}
}
try {
return getMessage(msgKey, "javah", versionRB.getString(versionKey));
}
catch (MissingResourceException e) {
return getMessage("version.unknown", System.getProperty("java.version"));
}
}
private Diagnostic<JavaFileObject> createDiagnostic(final String key, final Object... args) {
return new Diagnostic<JavaFileObject>() {
public Kind getKind() {
return Diagnostic.Kind.ERROR;
}
public JavaFileObject getSource() {
return null;
}
public long getPosition() {
return Diagnostic.NOPOS;
}
public long getStartPosition() {
return Diagnostic.NOPOS;
}
public long getEndPosition() {
return Diagnostic.NOPOS;
}
public long getLineNumber() {
return Diagnostic.NOPOS;
}
public long getColumnNumber() {
return Diagnostic.NOPOS;
}
public String getCode() {
return key;
}
public String getMessage(Locale locale) {
return JavahTask.this.getMessage(locale, key, args);
}
};
}
private String getMessage(String key, Object... args) {
return getMessage(task_locale, key, args);
}
private String getMessage(Locale locale, String key, Object... args) {
if (bundles == null) {
// could make this a HashMap<Locale,SoftReference<ResourceBundle>>
// and for efficiency, keep a hard reference to the bundle for the task
// locale
bundles = new HashMap<Locale, ResourceBundle>();
}
if (locale == null)
locale = Locale.getDefault();
ResourceBundle b = bundles.get(locale);
if (b == null) {
try {
b = ResourceBundle.getBundle("com.sun.tools.javah.resources.l10n", locale);
bundles.put(locale, b);
} catch (MissingResourceException e) {
throw new InternalError("Cannot find javah resource bundle for locale " + locale, e);
}
}
try {
return MessageFormat.format(b.getString(key), args);
} catch (MissingResourceException e) {
return key;
//throw new InternalError(e, key);
}
}
File ofile;
File odir;
String bootcp;
String usercp;
List<String> classes;
boolean verbose;
boolean noArgs;
boolean help;
boolean trace;
boolean version;
boolean fullVersion;
boolean jni;
boolean llni;
boolean doubleAlign;
boolean force;
Set<String> javac_extras = new LinkedHashSet<String>();
PrintWriter log;
JavaFileManager fileManager;
DiagnosticListener<? super JavaFileObject> diagnosticListener;
Locale task_locale;
Map<Locale, ResourceBundle> bundles;
private static final String progname = "javah";
@SupportedAnnotationTypes("*")
class JavahProcessor extends AbstractProcessor {
private Messager messager;
JavahProcessor(Gen g) {
this.g = g;
}
@Override
public SourceVersion getSupportedSourceVersion() {
// since this is co-bundled with javac, we can assume it supports
// the latest source version
return SourceVersion.latest();
}
@Override
public void init(ProcessingEnvironment pEnv) {
super.init(pEnv);
messager = processingEnv.getMessager();
}
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
try {
Set<TypeElement> classes = getAllClasses(ElementFilter.typesIn(roundEnv.getRootElements()));
if (classes.size() > 0) {
checkMethodParameters(classes);
g.setProcessingEnvironment(processingEnv);
g.setClasses(classes);
g.run();
}
} catch (CompletionFailure cf) {
messager.printMessage(ERROR, getMessage("class.not.found", cf.sym.getQualifiedName().toString()));
} catch (ClassNotFoundException cnfe) {
messager.printMessage(ERROR, getMessage("class.not.found", cnfe.getMessage()));
} catch (IOException ioe) {
messager.printMessage(ERROR, getMessage("io.exception", ioe.getMessage()));
} catch (Util.Exit e) {
exit = e;
}
return true;
}
private Set<TypeElement> getAllClasses(Set<? extends TypeElement> classes) {
Set<TypeElement> allClasses = new LinkedHashSet<TypeElement>();
getAllClasses0(classes, allClasses);
return allClasses;
}
private void getAllClasses0(Iterable<? extends TypeElement> classes, Set<TypeElement> allClasses) {
for (TypeElement c: classes) {
allClasses.add(c);
getAllClasses0(ElementFilter.typesIn(c.getEnclosedElements()), allClasses);
}
}
// 4942232:
// check that classes exist for all the parameters of native methods
private void checkMethodParameters(Set<TypeElement> classes) {
Types types = processingEnv.getTypeUtils();
for (TypeElement te: classes) {
for (ExecutableElement ee: ElementFilter.methodsIn(te.getEnclosedElements())) {
for (VariableElement ve: ee.getParameters()) {
TypeMirror tm = ve.asType();
checkMethodParametersVisitor.visit(tm, types);
}
}
}
}
private TypeVisitor<Void,Types> checkMethodParametersVisitor =
new SimpleTypeVisitor8<Void,Types>() {
@Override
public Void visitArray(ArrayType t, Types types) {
visit(t.getComponentType(), types);
return null;
}
@Override
public Void visitDeclared(DeclaredType t, Types types) {
t.asElement().getKind(); // ensure class exists
for (TypeMirror st: types.directSupertypes(t))
visit(st, types);
return null;
}
};
private Gen g;
private Util.Exit exit;
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javah;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.Locale;
import java.util.Set;
import javax.lang.model.SourceVersion;
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
/*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*/
public class JavahTool implements NativeHeaderTool {
public NativeHeaderTask getTask(Writer out,
JavaFileManager fileManager,
DiagnosticListener<? super JavaFileObject> diagnosticListener,
Iterable<String> options,
Iterable<String> classes) {
return new JavahTask(out, fileManager, diagnosticListener, options, classes);
}
public StandardJavaFileManager getStandardFileManager(DiagnosticListener<? super JavaFileObject> diagnosticListener, Locale locale, Charset charset) {
return JavahTask.getDefaultFileManager(diagnosticListener, null);
}
public int run(InputStream in, OutputStream out, OutputStream err, String... arguments) {
JavahTask t = new JavahTask(
JavahTask.getPrintWriterForStream(out),
null,
null,
Arrays.asList(arguments),
null);
return (t.run() ? 0 : 1);
}
public Set<SourceVersion> getSourceVersions() {
return EnumSet.allOf(SourceVersion.class);
}
public int isSupportedOption(String option) {
JavahTask.Option[] options = JavahTask.recognizedOptions;
for (int i = 0; i < options.length; i++) {
if (options[i].matches(option))
return (options[i].hasArg ? 1 : 0);
}
return -1;
}
}

View File

@@ -0,0 +1,680 @@
/*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javah;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVisitor;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.SimpleTypeVisitor8;
/*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*
* @author Sucheta Dambalkar(Revised)
*/
public class LLNI extends Gen {
protected final char innerDelim = '$'; /* For inner classes */
protected Set<String> doneHandleTypes;
List<VariableElement> fields;
List<ExecutableElement> methods;
private boolean doubleAlign;
private int padFieldNum = 0;
LLNI(boolean doubleAlign, Util util) {
super(util);
this.doubleAlign = doubleAlign;
}
protected String getIncludes() {
return "";
}
protected void write(OutputStream o, TypeElement clazz) throws Util.Exit {
try {
String cname = mangleClassName(clazz.getQualifiedName().toString());
PrintWriter pw = wrapWriter(o);
fields = ElementFilter.fieldsIn(clazz.getEnclosedElements());
methods = ElementFilter.methodsIn(clazz.getEnclosedElements());
generateDeclsForClass(pw, clazz, cname);
// FIXME check if errors occurred on the PrintWriter and throw exception if so
} catch (TypeSignature.SignatureException e) {
util.error("llni.sigerror", e.getMessage());
}
}
protected void generateDeclsForClass(PrintWriter pw,
TypeElement clazz, String cname)
throws TypeSignature.SignatureException, Util.Exit {
doneHandleTypes = new HashSet<String>();
/* The following handle types are predefined in "typedefs.h". Suppress
inclusion in the output by generating them "into the blue" here. */
genHandleType(null, "java.lang.Class");
genHandleType(null, "java.lang.ClassLoader");
genHandleType(null, "java.lang.Object");
genHandleType(null, "java.lang.String");
genHandleType(null, "java.lang.Thread");
genHandleType(null, "java.lang.ThreadGroup");
genHandleType(null, "java.lang.Throwable");
pw.println("/* LLNI Header for class " + clazz.getQualifiedName() + " */" + lineSep);
pw.println("#ifndef _Included_" + cname);
pw.println("#define _Included_" + cname);
pw.println("#include \"typedefs.h\"");
pw.println("#include \"llni.h\"");
pw.println("#include \"jni.h\"" + lineSep);
forwardDecls(pw, clazz);
structSectionForClass(pw, clazz, cname);
methodSectionForClass(pw, clazz, cname);
pw.println("#endif");
}
protected void genHandleType(PrintWriter pw, String clazzname) {
String cname = mangleClassName(clazzname);
if (!doneHandleTypes.contains(cname)) {
doneHandleTypes.add(cname);
if (pw != null) {
pw.println("#ifndef DEFINED_" + cname);
pw.println(" #define DEFINED_" + cname);
pw.println(" GEN_HANDLE_TYPES(" + cname + ");");
pw.println("#endif" + lineSep);
}
}
}
protected String mangleClassName(String s) {
return s.replace('.', '_')
.replace('/', '_')
.replace(innerDelim, '_');
}
protected void forwardDecls(PrintWriter pw, TypeElement clazz)
throws TypeSignature.SignatureException {
TypeElement object = elems.getTypeElement("java.lang.Object");
if (clazz.equals(object))
return;
genHandleType(pw, clazz.getQualifiedName().toString());
TypeElement superClass = (TypeElement) (types.asElement(clazz.getSuperclass()));
if (superClass != null) {
String superClassName = superClass.getQualifiedName().toString();
forwardDecls(pw, superClass);
}
for (VariableElement field: fields) {
if (!field.getModifiers().contains(Modifier.STATIC)) {
TypeMirror t = types.erasure(field.asType());
TypeSignature newTypeSig = new TypeSignature(elems);
String tname = newTypeSig.qualifiedTypeName(t);
String sig = newTypeSig.getTypeSignature(tname);
if (sig.charAt(0) != '[')
forwardDeclsFromSig(pw, sig);
}
}
for (ExecutableElement method: methods) {
if (method.getModifiers().contains(Modifier.NATIVE)) {
TypeMirror retType = types.erasure(method.getReturnType());
String typesig = signature(method);
TypeSignature newTypeSig = new TypeSignature(elems);
String sig = newTypeSig.getTypeSignature(typesig, retType);
if (sig.charAt(0) != '[')
forwardDeclsFromSig(pw, sig);
}
}
}
protected void forwardDeclsFromSig(PrintWriter pw, String sig) {
int len = sig.length();
int i = sig.charAt(0) == '(' ? 1 : 0;
/* Skip the initial "(". */
while (i < len) {
if (sig.charAt(i) == 'L') {
int j = i + 1;
while (sig.charAt(j) != ';') j++;
genHandleType(pw, sig.substring(i + 1, j));
i = j + 1;
} else {
i++;
}
}
}
protected void structSectionForClass(PrintWriter pw,
TypeElement jclazz, String cname) {
String jname = jclazz.getQualifiedName().toString();
if (cname.equals("java_lang_Object")) {
pw.println("/* struct java_lang_Object is defined in typedefs.h. */");
pw.println();
return;
}
pw.println("#if !defined(__i386)");
pw.println("#pragma pack(4)");
pw.println("#endif");
pw.println();
pw.println("struct " + cname + " {");
pw.println(" ObjHeader h;");
pw.print(fieldDefs(jclazz, cname));
if (jname.equals("java.lang.Class"))
pw.println(" Class *LLNI_mask(cClass);" +
" /* Fake field; don't access (see oobj.h) */");
pw.println("};" + lineSep + lineSep + "#pragma pack()");
pw.println();
return;
}
private static class FieldDefsRes {
public String className; /* Name of the current class. */
public FieldDefsRes parent;
public String s;
public int byteSize;
public boolean bottomMost;
public boolean printedOne = false;
FieldDefsRes(TypeElement clazz, FieldDefsRes parent, boolean bottomMost) {
this.className = clazz.getQualifiedName().toString();
this.parent = parent;
this.bottomMost = bottomMost;
int byteSize = 0;
if (parent == null) this.s = "";
else this.s = parent.s;
}
}
/* Returns "true" iff added a field. */
private boolean doField(FieldDefsRes res, VariableElement field,
String cname, boolean padWord) {
String fieldDef = addStructMember(field, cname, padWord);
if (fieldDef != null) {
if (!res.printedOne) { /* add separator */
if (res.bottomMost) {
if (res.s.length() != 0)
res.s = res.s + " /* local members: */" + lineSep;
} else {
res.s = res.s + " /* inherited members from " +
res.className + ": */" + lineSep;
}
res.printedOne = true;
}
res.s = res.s + fieldDef;
return true;
}
// Otherwise.
return false;
}
private int doTwoWordFields(FieldDefsRes res, TypeElement clazz,
int offset, String cname, boolean padWord) {
boolean first = true;
List<VariableElement> fields = ElementFilter.fieldsIn(clazz.getEnclosedElements());
for (VariableElement field: fields) {
TypeKind tk = field.asType().getKind();
boolean twoWords = (tk == TypeKind.LONG || tk == TypeKind.DOUBLE);
if (twoWords && doField(res, field, cname, first && padWord)) {
offset += 8; first = false;
}
}
return offset;
}
String fieldDefs(TypeElement clazz, String cname) {
FieldDefsRes res = fieldDefs(clazz, cname, true);
return res.s;
}
FieldDefsRes fieldDefs(TypeElement clazz, String cname,
boolean bottomMost){
FieldDefsRes res;
int offset;
boolean didTwoWordFields = false;
TypeElement superclazz = (TypeElement) types.asElement(clazz.getSuperclass());
if (superclazz != null) {
String supername = superclazz.getQualifiedName().toString();
res = new FieldDefsRes(clazz,
fieldDefs(superclazz, cname, false),
bottomMost);
offset = res.parent.byteSize;
} else {
res = new FieldDefsRes(clazz, null, bottomMost);
offset = 0;
}
List<VariableElement> fields = ElementFilter.fieldsIn(clazz.getEnclosedElements());
for (VariableElement field: fields) {
if (doubleAlign && !didTwoWordFields && (offset % 8) == 0) {
offset = doTwoWordFields(res, clazz, offset, cname, false);
didTwoWordFields = true;
}
TypeKind tk = field.asType().getKind();
boolean twoWords = (tk == TypeKind.LONG || tk == TypeKind.DOUBLE);
if (!doubleAlign || !twoWords) {
if (doField(res, field, cname, false)) offset += 4;
}
}
if (doubleAlign && !didTwoWordFields) {
if ((offset % 8) != 0) offset += 4;
offset = doTwoWordFields(res, clazz, offset, cname, true);
}
res.byteSize = offset;
return res;
}
/* OVERRIDE: This method handles instance fields */
protected String addStructMember(VariableElement member, String cname,
boolean padWord) {
String res = null;
if (member.getModifiers().contains(Modifier.STATIC)) {
res = addStaticStructMember(member, cname);
// if (res == null) /* JNI didn't handle it, print comment. */
// res = " /* Inaccessible static: " + member + " */" + lineSep;
} else {
TypeMirror mt = types.erasure(member.asType());
if (padWord) res = " java_int padWord" + padFieldNum++ + ";" + lineSep;
res = " " + llniType(mt, false, false) + " " + llniFieldName(member);
if (isLongOrDouble(mt)) res = res + "[2]";
res = res + ";" + lineSep;
}
return res;
}
static private final boolean isWindows =
System.getProperty("os.name").startsWith("Windows");
/*
* This method only handles static final fields.
*/
protected String addStaticStructMember(VariableElement field, String cname) {
String res = null;
Object exp = null;
if (!field.getModifiers().contains(Modifier.STATIC))
return res;
if (!field.getModifiers().contains(Modifier.FINAL))
return res;
exp = field.getConstantValue();
if (exp != null) {
/* Constant. */
String cn = cname + "_" + field.getSimpleName();
String suffix = null;
long val = 0;
/* Can only handle int, long, float, and double fields. */
if (exp instanceof Byte
|| exp instanceof Short
|| exp instanceof Integer) {
suffix = "L";
val = ((Number)exp).intValue();
}
else if (exp instanceof Long) {
// Visual C++ supports the i64 suffix, not LL
suffix = isWindows ? "i64" : "LL";
val = ((Long)exp).longValue();
}
else if (exp instanceof Float) suffix = "f";
else if (exp instanceof Double) suffix = "";
else if (exp instanceof Character) {
suffix = "L";
Character ch = (Character) exp;
val = ((int) ch) & 0xffff;
}
if (suffix != null) {
// Some compilers will generate a spurious warning
// for the integer constants for Integer.MIN_VALUE
// and Long.MIN_VALUE so we handle them specially.
if ((suffix.equals("L") && (val == Integer.MIN_VALUE)) ||
(suffix.equals("LL") && (val == Long.MIN_VALUE))) {
res = " #undef " + cn + lineSep
+ " #define " + cn
+ " (" + (val + 1) + suffix + "-1)" + lineSep;
} else if (suffix.equals("L") || suffix.endsWith("LL")) {
res = " #undef " + cn + lineSep
+ " #define " + cn + " " + val + suffix + lineSep;
} else {
res = " #undef " + cn + lineSep
+ " #define " + cn + " " + exp + suffix + lineSep;
}
}
}
return res;
}
protected void methodSectionForClass(PrintWriter pw,
TypeElement clazz, String cname)
throws TypeSignature.SignatureException, Util.Exit {
String methods = methodDecls(clazz, cname);
if (methods.length() != 0) {
pw.println("/* Native method declarations: */" + lineSep);
pw.println("#ifdef __cplusplus");
pw.println("extern \"C\" {");
pw.println("#endif" + lineSep);
pw.println(methods);
pw.println("#ifdef __cplusplus");
pw.println("}");
pw.println("#endif");
}
}
protected String methodDecls(TypeElement clazz, String cname)
throws TypeSignature.SignatureException, Util.Exit {
String res = "";
for (ExecutableElement method: methods) {
if (method.getModifiers().contains(Modifier.NATIVE))
res = res + methodDecl(method, clazz, cname);
}
return res;
}
protected String methodDecl(ExecutableElement method,
TypeElement clazz, String cname)
throws TypeSignature.SignatureException, Util.Exit {
String res = null;
TypeMirror retType = types.erasure(method.getReturnType());
String typesig = signature(method);
TypeSignature newTypeSig = new TypeSignature(elems);
String sig = newTypeSig.getTypeSignature(typesig, retType);
boolean longName = needLongName(method, clazz);
if (sig.charAt(0) != '(')
util.error("invalid.method.signature", sig);
res = "JNIEXPORT " + jniType(retType) + " JNICALL" + lineSep + jniMethodName(method, cname, longName)
+ "(JNIEnv *, " + cRcvrDecl(method, cname);
List<? extends VariableElement> params = method.getParameters();
List<TypeMirror> argTypes = new ArrayList<TypeMirror>();
for (VariableElement p: params){
argTypes.add(types.erasure(p.asType()));
}
/* It would have been nice to include the argument names in the
declaration, but there seems to be a bug in the "BinaryField"
class, causing the getArguments() method to return "null" for
most (non-constructor) methods. */
for (TypeMirror argType: argTypes)
res = res + ", " + jniType(argType);
res = res + ");" + lineSep;
return res;
}
protected final boolean needLongName(ExecutableElement method,
TypeElement clazz) {
Name methodName = method.getSimpleName();
for (ExecutableElement memberMethod: methods) {
if ((memberMethod != method) &&
memberMethod.getModifiers().contains(Modifier.NATIVE) &&
(methodName.equals(memberMethod.getSimpleName())))
return true;
}
return false;
}
protected final String jniMethodName(ExecutableElement method, String cname,
boolean longName)
throws TypeSignature.SignatureException {
String res = "Java_" + cname + "_" + method.getSimpleName();
if (longName) {
TypeMirror mType = types.erasure(method.getReturnType());
List<? extends VariableElement> params = method.getParameters();
List<TypeMirror> argTypes = new ArrayList<TypeMirror>();
for (VariableElement param: params) {
argTypes.add(types.erasure(param.asType()));
}
res = res + "__";
for (TypeMirror t: argTypes) {
String tname = t.toString();
TypeSignature newTypeSig = new TypeSignature(elems);
String sig = newTypeSig.getTypeSignature(tname);
res = res + nameToIdentifier(sig);
}
}
return res;
}
// copied from JNI.java
protected final String jniType(TypeMirror t) throws Util.Exit {
TypeElement throwable = elems.getTypeElement("java.lang.Throwable");
TypeElement jClass = elems.getTypeElement("java.lang.Class");
TypeElement jString = elems.getTypeElement("java.lang.String");
Element tclassDoc = types.asElement(t);
switch (t.getKind()) {
case ARRAY: {
TypeMirror ct = ((ArrayType) t).getComponentType();
switch (ct.getKind()) {
case BOOLEAN: return "jbooleanArray";
case BYTE: return "jbyteArray";
case CHAR: return "jcharArray";
case SHORT: return "jshortArray";
case INT: return "jintArray";
case LONG: return "jlongArray";
case FLOAT: return "jfloatArray";
case DOUBLE: return "jdoubleArray";
case ARRAY:
case DECLARED: return "jobjectArray";
default: throw new Error(ct.toString());
}
}
case VOID: return "void";
case BOOLEAN: return "jboolean";
case BYTE: return "jbyte";
case CHAR: return "jchar";
case SHORT: return "jshort";
case INT: return "jint";
case LONG: return "jlong";
case FLOAT: return "jfloat";
case DOUBLE: return "jdouble";
case DECLARED: {
if (tclassDoc.equals(jString))
return "jstring";
else if (types.isAssignable(t, throwable.asType()))
return "jthrowable";
else if (types.isAssignable(t, jClass.asType()))
return "jclass";
else
return "jobject";
}
}
util.bug("jni.unknown.type");
return null; /* dead code. */
}
protected String llniType(TypeMirror t, boolean handleize, boolean longDoubleOK) {
String res = null;
switch (t.getKind()) {
case ARRAY: {
TypeMirror ct = ((ArrayType) t).getComponentType();
switch (ct.getKind()) {
case BOOLEAN: res = "IArrayOfBoolean"; break;
case BYTE: res = "IArrayOfByte"; break;
case CHAR: res = "IArrayOfChar"; break;
case SHORT: res = "IArrayOfShort"; break;
case INT: res = "IArrayOfInt"; break;
case LONG: res = "IArrayOfLong"; break;
case FLOAT: res = "IArrayOfFloat"; break;
case DOUBLE: res = "IArrayOfDouble"; break;
case ARRAY:
case DECLARED: res = "IArrayOfRef"; break;
default: throw new Error(ct.getKind() + " " + ct);
}
if (!handleize) res = "DEREFERENCED_" + res;
break;
}
case VOID:
res = "void";
break;
case BOOLEAN:
case BYTE:
case CHAR:
case SHORT:
case INT:
res = "java_int" ;
break;
case LONG:
res = longDoubleOK ? "java_long" : "val32 /* java_long */";
break;
case FLOAT:
res = "java_float";
break;
case DOUBLE:
res = longDoubleOK ? "java_double" : "val32 /* java_double */";
break;
case DECLARED:
TypeElement e = (TypeElement) types.asElement(t);
res = "I" + mangleClassName(e.getQualifiedName().toString());
if (!handleize) res = "DEREFERENCED_" + res;
break;
default:
throw new Error(t.getKind() + " " + t); // FIXME
}
return res;
}
protected final String cRcvrDecl(Element field, String cname) {
return (field.getModifiers().contains(Modifier.STATIC) ? "jclass" : "jobject");
}
protected String maskName(String s) {
return "LLNI_mask(" + s + ")";
}
protected String llniFieldName(VariableElement field) {
return maskName(field.getSimpleName().toString());
}
protected final boolean isLongOrDouble(TypeMirror t) {
TypeVisitor<Boolean,Void> v = new SimpleTypeVisitor8<Boolean,Void>() {
public Boolean defaultAction(TypeMirror t, Void p){
return false;
}
public Boolean visitArray(ArrayType t, Void p) {
return visit(t.getComponentType(), p);
}
public Boolean visitPrimitive(PrimitiveType t, Void p) {
TypeKind tk = t.getKind();
return (tk == TypeKind.LONG || tk == TypeKind.DOUBLE);
}
};
return v.visit(t, null);
}
/* Do unicode to ansi C identifier conversion.
%%% This may not be right, but should be called more often. */
protected final String nameToIdentifier(String name) {
int len = name.length();
StringBuilder buf = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = name.charAt(i);
if (isASCIILetterOrDigit(c))
buf.append(c);
else if (c == '/')
buf.append('_');
else if (c == '.')
buf.append('_');
else if (c == '_')
buf.append("_1");
else if (c == ';')
buf.append("_2");
else if (c == '[')
buf.append("_3");
else
buf.append("_0" + ((int)c));
}
return new String(buf);
}
protected final boolean isASCIILetterOrDigit(char c) {
if (((c >= 'A') && (c <= 'Z')) ||
((c >= 'a') && (c <= 'z')) ||
((c >= '0') && (c <= '9')))
return true;
else
return false;
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javah;
import java.io.PrintWriter;
/**
* Main entry point.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class Main {
/**
* Main entry point for the launcher.
* Note: This method calls System.exit.
* @param args command line arguments
*/
public static void main(String[] args) {
JavahTask t = new JavahTask();
int rc = t.run(args);
System.exit(rc);
}
/**
* Entry point that does <i>not</i> call System.exit.
* @param args command line arguments
* @param out output stream
* @return an exit code. 0 means success, non-zero means an error occurred.
*/
public static int run(String[] args, PrintWriter out) {
JavahTask t = new JavahTask();
t.setLog(out);
return t.run(args);
}
}

View File

@@ -0,0 +1,190 @@
/*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javah;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
/**
* A utility for mangling java identifiers into C names. Should make
* this more fine grained and distribute the functionality to the
* generators.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*
* @author Sucheta Dambalkar(Revised)
*/
public class Mangle {
public static class Type {
public static final int CLASS = 1;
public static final int FIELDSTUB = 2;
public static final int FIELD = 3;
public static final int JNI = 4;
public static final int SIGNATURE = 5;
public static final int METHOD_JDK_1 = 6;
public static final int METHOD_JNI_SHORT = 7;
public static final int METHOD_JNI_LONG = 8;
};
private Elements elems;
private Types types;
Mangle(Elements elems, Types types) {
this.elems = elems;
this.types = types;
}
public final String mangle(CharSequence name, int mtype) {
StringBuilder result = new StringBuilder(100);
int length = name.length();
for (int i = 0; i < length; i++) {
char ch = name.charAt(i);
if (isalnum(ch)) {
result.append(ch);
} else if ((ch == '.') &&
mtype == Mangle.Type.CLASS) {
result.append('_');
} else if (( ch == '$') &&
mtype == Mangle.Type.CLASS) {
result.append('_');
result.append('_');
} else if (ch == '_' && mtype == Mangle.Type.FIELDSTUB) {
result.append('_');
} else if (ch == '_' && mtype == Mangle.Type.CLASS) {
result.append('_');
} else if (mtype == Mangle.Type.JNI) {
String esc = null;
if (ch == '_')
esc = "_1";
else if (ch == '.')
esc = "_";
else if (ch == ';')
esc = "_2";
else if (ch == '[')
esc = "_3";
if (esc != null) {
result.append(esc);
} else {
result.append(mangleChar(ch));
}
} else if (mtype == Mangle.Type.SIGNATURE) {
if (isprint(ch)) {
result.append(ch);
} else {
result.append(mangleChar(ch));
}
} else {
result.append(mangleChar(ch));
}
}
return result.toString();
}
public String mangleMethod(ExecutableElement method, TypeElement clazz,
int mtype) throws TypeSignature.SignatureException {
StringBuilder result = new StringBuilder(100);
result.append("Java_");
if (mtype == Mangle.Type.METHOD_JDK_1) {
result.append(mangle(clazz.getQualifiedName(), Mangle.Type.CLASS));
result.append('_');
result.append(mangle(method.getSimpleName(),
Mangle.Type.FIELD));
result.append("_stub");
return result.toString();
}
/* JNI */
result.append(mangle(getInnerQualifiedName(clazz), Mangle.Type.JNI));
result.append('_');
result.append(mangle(method.getSimpleName(),
Mangle.Type.JNI));
if (mtype == Mangle.Type.METHOD_JNI_LONG) {
result.append("__");
String typesig = signature(method);
TypeSignature newTypeSig = new TypeSignature(elems);
String sig = newTypeSig.getTypeSignature(typesig, method.getReturnType());
sig = sig.substring(1);
sig = sig.substring(0, sig.lastIndexOf(')'));
sig = sig.replace('/', '.');
result.append(mangle(sig, Mangle.Type.JNI));
}
return result.toString();
}
//where
private String getInnerQualifiedName(TypeElement clazz) {
return elems.getBinaryName(clazz).toString();
}
public final String mangleChar(char ch) {
String s = Integer.toHexString(ch);
int nzeros = 5 - s.length();
char[] result = new char[6];
result[0] = '_';
for (int i = 1; i <= nzeros; i++)
result[i] = '0';
for (int i = nzeros+1, j = 0; i < 6; i++, j++)
result[i] = s.charAt(j);
return new String(result);
}
// Warning: duplicated in Gen
private String signature(ExecutableElement e) {
StringBuilder sb = new StringBuilder();
String sep = "(";
for (VariableElement p: e.getParameters()) {
sb.append(sep);
sb.append(types.erasure(p.asType()).toString());
sep = ",";
}
sb.append(")");
return sb.toString();
}
/* Warning: Intentional ASCII operation. */
private static final boolean isalnum(char ch) {
return ch <= 0x7f && /* quick test */
((ch >= 'A' && ch <= 'Z') ||
(ch >= 'a' && ch <= 'z') ||
(ch >= '0' && ch <= '9'));
}
/* Warning: Intentional ASCII operation. */
private static final boolean isprint(char ch) {
return ch >= 32 && ch <= 126;
}
}

View File

@@ -0,0 +1,149 @@
/*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javah; //javax.tools;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.Locale;
import java.util.concurrent.Callable;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.OptionChecker;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.Tool;
/**
* This class is intended to be put in javax.tools.
*
* @see DiagnosticListener
* @see Diagnostic
* @see JavaFileManager
* @since 1.7
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public interface NativeHeaderTool extends Tool, OptionChecker {
/**
* Creates a future for a native header task with the given
* components and arguments. The task might not have
* completed as described in the NativeHeaderTask interface.
*
* <p>If a file manager is provided, it must be able to handle all
* locations defined in {@link StandardLocation}.
*
* @param out a Writer for additional output from the task;
* use {@code System.err} if {@code null}
* @param fileManager a file manager; if {@code null} use the
* task's standard filemanager
* @param diagnosticListener a diagnostic listener; if {@code
* null} use the compiler's default method for reporting
* diagnostics
* @param options task options, {@code null} means no options
* @param classes class names for which native headers should be generated
* @return an object representing the task to be done
* @throws RuntimeException if an unrecoverable error
* occurred in a user supplied component. The
* {@linkplain Throwable#getCause() cause} will be the error in
* user code.
* @throws IllegalArgumentException if any of the given
* compilation units are of other kind than
* {@linkplain JavaFileObject.Kind#SOURCE source}
*/
NativeHeaderTask getTask(Writer out,
JavaFileManager fileManager,
DiagnosticListener<? super JavaFileObject> diagnosticListener,
Iterable<String> options,
Iterable<String> classes);
/**
* Gets a new instance of the standard file manager implementation
* for this tool. The file manager will use the given diagnostic
* listener for producing any non-fatal diagnostics. Fatal errors
* will be signalled with the appropriate exceptions.
*
* <p>The standard file manager will be automatically reopened if
* it is accessed after calls to {@code flush} or {@code close}.
* The standard file manager must be usable with other tools.
*
* @param diagnosticListener a diagnostic listener for non-fatal
* diagnostics; if {@code null} use the tool's default method
* for reporting diagnostics
* @param locale the locale to apply when formatting diagnostics;
* {@code null} means the {@linkplain Locale#getDefault() default locale}.
* @param charset the character set used for decoding bytes; if
* {@code null} use the platform default
* @return the standard file manager
*/
StandardJavaFileManager getStandardFileManager(
DiagnosticListener<? super JavaFileObject> diagnosticListener,
Locale locale,
Charset charset);
/**
* Interface representing a future for a native header task. The
* task has not yet started. To start the task, call
* the {@linkplain #call call} method.
*
* <p>Before calling the call method, additional aspects of the
* task can be configured, for example, by calling the
* {@linkplain #setLocale setLocale} method.
*/
interface NativeHeaderTask extends Callable<Boolean> {
/**
* Set the locale to be applied when formatting diagnostics and
* other localized data.
*
* @param locale the locale to apply; {@code null} means apply no
* locale
* @throws IllegalStateException if the task has started
*/
void setLocale(Locale locale);
/**
* Performs this native header task. The task may only
* be performed once. Subsequent calls to this method throw
* IllegalStateException.
*
* @return true if and only all the files were processed without errors;
* false otherwise
*
* @throws RuntimeException if an unrecoverable error occurred
* in a user-supplied component. The
* {@linkplain Throwable#getCause() cause} will be the error
* in user code.
* @throws IllegalStateException if called more than once
*/
Boolean call();
}
}

View File

@@ -0,0 +1,278 @@
/*
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javah;
import java.util.*;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.NoType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.type.TypeVisitor;
import javax.lang.model.util.Elements;
import javax.lang.model.util.SimpleTypeVisitor8;
/**
* Returns internal type signature.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*
* @author Sucheta Dambalkar
*/
public class TypeSignature {
static class SignatureException extends Exception {
private static final long serialVersionUID = 1L;
SignatureException(String reason) {
super(reason);
}
}
Elements elems;
/* Signature Characters */
private static final String SIG_VOID = "V";
private static final String SIG_BOOLEAN = "Z";
private static final String SIG_BYTE = "B";
private static final String SIG_CHAR = "C";
private static final String SIG_SHORT = "S";
private static final String SIG_INT = "I";
private static final String SIG_LONG = "J";
private static final String SIG_FLOAT = "F";
private static final String SIG_DOUBLE = "D";
private static final String SIG_ARRAY = "[";
private static final String SIG_CLASS = "L";
public TypeSignature(Elements elems){
this.elems = elems;
}
/*
* Returns the type signature of a field according to JVM specs
*/
public String getTypeSignature(String javasignature) throws SignatureException {
return getParamJVMSignature(javasignature);
}
/*
* Returns the type signature of a method according to JVM specs
*/
public String getTypeSignature(String javasignature, TypeMirror returnType)
throws SignatureException {
String signature = null; //Java type signature.
String typeSignature = null; //Internal type signature.
List<String> params = new ArrayList<String>(); //List of parameters.
String paramsig = null; //Java parameter signature.
String paramJVMSig = null; //Internal parameter signature.
String returnSig = null; //Java return type signature.
String returnJVMType = null; //Internal return type signature.
int dimensions = 0; //Array dimension.
int startIndex = -1;
int endIndex = -1;
StringTokenizer st = null;
int i = 0;
// Gets the actual java signature without parentheses.
if (javasignature != null) {
startIndex = javasignature.indexOf("(");
endIndex = javasignature.indexOf(")");
}
if (((startIndex != -1) && (endIndex != -1))
&&(startIndex+1 < javasignature.length())
&&(endIndex < javasignature.length())) {
signature = javasignature.substring(startIndex+1, endIndex);
}
// Separates parameters.
if (signature != null) {
if (signature.indexOf(",") != -1) {
st = new StringTokenizer(signature, ",");
if (st != null) {
while (st.hasMoreTokens()) {
params.add(st.nextToken());
}
}
} else {
params.add(signature);
}
}
/* JVM type signature. */
typeSignature = "(";
// Gets indivisual internal parameter signature.
while (params.isEmpty() != true) {
paramsig = params.remove(i).trim();
paramJVMSig = getParamJVMSignature(paramsig);
if (paramJVMSig != null) {
typeSignature += paramJVMSig;
}
}
typeSignature += ")";
// Get internal return type signature.
returnJVMType = "";
if (returnType != null) {
dimensions = dimensions(returnType);
}
//Gets array dimension of return type.
while (dimensions-- > 0) {
returnJVMType += "[";
}
if (returnType != null) {
returnSig = qualifiedTypeName(returnType);
returnJVMType += getComponentType(returnSig);
} else {
System.out.println("Invalid return type.");
}
typeSignature += returnJVMType;
return typeSignature;
}
/*
* Returns internal signature of a parameter.
*/
private String getParamJVMSignature(String paramsig) throws SignatureException {
String paramJVMSig = "";
String componentType ="";
if(paramsig != null){
if(paramsig.indexOf("[]") != -1) {
// Gets array dimension.
int endindex = paramsig.indexOf("[]");
componentType = paramsig.substring(0, endindex);
String dimensionString = paramsig.substring(endindex);
if(dimensionString != null){
while(dimensionString.indexOf("[]") != -1){
paramJVMSig += "[";
int beginindex = dimensionString.indexOf("]") + 1;
if(beginindex < dimensionString.length()){
dimensionString = dimensionString.substring(beginindex);
}else
dimensionString = "";
}
}
} else componentType = paramsig;
paramJVMSig += getComponentType(componentType);
}
return paramJVMSig;
}
/*
* Returns internal signature of a component.
*/
private String getComponentType(String componentType) throws SignatureException {
String JVMSig = "";
if(componentType != null){
if(componentType.equals("void")) JVMSig += SIG_VOID ;
else if(componentType.equals("boolean")) JVMSig += SIG_BOOLEAN ;
else if(componentType.equals("byte")) JVMSig += SIG_BYTE ;
else if(componentType.equals("char")) JVMSig += SIG_CHAR ;
else if(componentType.equals("short")) JVMSig += SIG_SHORT ;
else if(componentType.equals("int")) JVMSig += SIG_INT ;
else if(componentType.equals("long")) JVMSig += SIG_LONG ;
else if(componentType.equals("float")) JVMSig += SIG_FLOAT ;
else if(componentType.equals("double")) JVMSig += SIG_DOUBLE ;
else {
if(!componentType.equals("")){
TypeElement classNameDoc = elems.getTypeElement(componentType);
if(classNameDoc == null){
throw new SignatureException(componentType);
}else {
String classname = classNameDoc.getQualifiedName().toString();
String newclassname = classname.replace('.', '/');
JVMSig += "L";
JVMSig += newclassname;
JVMSig += ";";
}
}
}
}
return JVMSig;
}
int dimensions(TypeMirror t) {
if (t.getKind() != TypeKind.ARRAY)
return 0;
return 1 + dimensions(((ArrayType) t).getComponentType());
}
String qualifiedTypeName(TypeMirror type) {
TypeVisitor<Name, Void> v = new SimpleTypeVisitor8<Name, Void>() {
@Override
public Name visitArray(ArrayType t, Void p) {
return t.getComponentType().accept(this, p);
}
@Override
public Name visitDeclared(DeclaredType t, Void p) {
return ((TypeElement) t.asElement()).getQualifiedName();
}
@Override
public Name visitPrimitive(PrimitiveType t, Void p) {
return elems.getName(t.toString());
}
@Override
public Name visitNoType(NoType t, Void p) {
if (t.getKind() == TypeKind.VOID)
return elems.getName("void");
return defaultAction(t, p);
}
@Override
public Name visitTypeVariable(TypeVariable t, Void p) {
return t.getUpperBound().accept(this, p);
}
};
return v.visit(type).toString();
}
}

View File

@@ -0,0 +1,186 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javah;
import java.io.PrintWriter;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.MissingResourceException;
import javax.tools.Diagnostic;
import javax.tools.Diagnostic.Kind;
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileObject;
/**
* Messages, verbose and error handling support.
*
* For errors, the failure modes are:
* error -- User did something wrong
* bug -- Bug has occurred in javah
* fatal -- We can't even find resources, so bail fast, don't localize
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*/
public class Util {
/** Exit is used to replace the use of System.exit in the original javah.
*/
public static class Exit extends Error {
private static final long serialVersionUID = 430820978114067221L;
Exit(int exitValue) {
this(exitValue, null);
}
Exit(int exitValue, Throwable cause) {
super(cause);
this.exitValue = exitValue;
this.cause = cause;
}
Exit(Exit e) {
this(e.exitValue, e.cause);
}
public final int exitValue;
public final Throwable cause;
}
/*
* Help for verbosity.
*/
public boolean verbose = false;
public PrintWriter log;
public DiagnosticListener<? super JavaFileObject> dl;
Util(PrintWriter log, DiagnosticListener<? super JavaFileObject> dl) {
this.log = log;
this.dl = dl;
}
public void log(String s) {
log.println(s);
}
/*
* Help for loading localized messages.
*/
private ResourceBundle m;
private void initMessages() throws Exit {
try {
m = ResourceBundle.getBundle("com.sun.tools.javah.resources.l10n");
} catch (MissingResourceException mre) {
fatal("Error loading resources. Please file a bug report.", mre);
}
}
private String getText(String key, Object... args) throws Exit {
if (m == null)
initMessages();
try {
return MessageFormat.format(m.getString(key), args);
} catch (MissingResourceException e) {
fatal("Key " + key + " not found in resources.", e);
}
return null; /* dead code */
}
/*
* Usage message.
*/
public void usage() throws Exit {
log.println(getText("usage"));
}
public void version() throws Exit {
log.println(getText("javah.version",
System.getProperty("java.version"), null));
}
/*
* Failure modes.
*/
public void bug(String key) throws Exit {
bug(key, null);
}
public void bug(String key, Exception e) throws Exit {
dl.report(createDiagnostic(Diagnostic.Kind.ERROR, key));
dl.report(createDiagnostic(Diagnostic.Kind.NOTE, "bug.report"));
throw new Exit(11, e);
}
public void error(String key, Object... args) throws Exit {
dl.report(createDiagnostic(Diagnostic.Kind.ERROR, key, args));
throw new Exit(15);
}
private void fatal(String msg, Exception e) throws Exit {
dl.report(createDiagnostic(Diagnostic.Kind.ERROR, "", msg));
throw new Exit(10, e);
}
private Diagnostic<JavaFileObject> createDiagnostic(
final Diagnostic.Kind kind, final String code, final Object... args) {
return new Diagnostic<JavaFileObject>() {
public String getCode() {
return code;
}
public long getColumnNumber() {
return Diagnostic.NOPOS;
}
public long getEndPosition() {
return Diagnostic.NOPOS;
}
public Kind getKind() {
return kind;
}
public long getLineNumber() {
return Diagnostic.NOPOS;
}
public String getMessage(Locale locale) {
if (code.length() == 0)
return (String) args[0];
return getText(code, args); // FIXME locale
}
public long getPosition() {
return Diagnostic.NOPOS;
}
public JavaFileObject getSource() {
return null;
}
public long getStartPosition() {
return Diagnostic.NOPOS;
}
};
}
}

View File

@@ -0,0 +1,58 @@
package com.sun.tools.javah.resources;
public final class l10n extends java.util.ListResourceBundle {
protected final Object[][] getContents() {
return new Object[][] {
{ "at.args.cant.read", "Can''t read command line arguments from file {1}." },
{ "at.args.file.not.found", "Can''t find file {0}." },
{ "at.args.io.exception", "The following I/O problem was encountered when processing an @ argument on the command line: {0}." },
{ "cant.create.dir", "The directory {0} could not be create for output." },
{ "class.not.found", "Class {0} could not be found." },
{ "dir.file.mixed", "Can''t mix options -d and -o. Try -help." },
{ "encoding.iso8859_1.not.found", "ISO8859_1 converter was not found for output. This is probably due to an error in the installation installation." },
{ "err.cant.use.option.for.fm", "Can't use {0} option with given file manager" },
{ "err.internal.error", "Internal error: {0}" },
{ "err.ioerror", "IO error: {0}" },
{ "err.missing.arg", "value missing for {0}" },
{ "err.no.classes.specified", "no classes specified" },
{ "err.prefix", "Error:" },
{ "err.unknown.option", "unknown option: {0}" },
{ "invalid.method.signature", "Invalid method signature: {0}" },
{ "io.exception", "Can''t recover from an I/O error with the following message: {0}." },
{ "javah.fullVersion", "{0} full version \"{1}\"" },
{ "javah.version", "{0} version \"{1}\"" },
{ "jni.llni.mixed", "Can''t mix options -jni and -llni. Try -help." },
{ "jni.no.stubs", "JNI does not require stubs, please refer to the JNI documentation." },
{ "jni.sigerror", "Cannot determine signature for {0}" },
{ "jni.unknown.type", "An unknown type encountered (JNI)." },
{ "main.opt.bootclasspath", " -bootclasspath <path> Path from which to load bootstrap classes" },
{ "main.opt.classpath", " -classpath <path> Path from which to load classes" },
{ "main.opt.cp", " -cp <path> Path from which to load classes" },
{ "main.opt.d", " -d <dir> Output directory" },
{ "main.opt.force", " -force Always write output files" },
{ "main.opt.h", " -h --help -? Print this message" },
{ "main.opt.jni", " -jni Generate JNI-style header file (default)" },
{ "main.opt.o", " -o <file> Output file (only one of -d or -o may be used)" },
{ "main.opt.v", " -v -verbose Enable verbose output" },
{ "main.opt.version", " -version Print version information" },
{ "main.usage", "Usage: \n javah [options] <classes>\nwhere [options] include:" },
{ "main.usage.foot", "<classes> are specified with their fully qualified names\n(for example, java.lang.Object)." },
{ "no.bootclasspath.specified", "No bootclasspath was specified on the command line. Try -help." },
{ "no.classes.specified", "No classes were specified on the command line. Try -help." },
{ "no.classpath.specified", "No classpath was specified on the command line. Try -help." },
{ "no.outputdir.specified", "No output directory was specified on the command line. Try -help." },
{ "no.outputfile.specified", "No outputfile was specified on the command line. Try -help." },
{ "old.jni.mixed", "Can''t mix options -jni and -old. Try -help." },
{ "old.llni.mixed", "Can''t mix options -old and -llni. Try -help." },
{ "old.not.supported", "Option -old not supported by this version of javah." },
{ "super.class.not.found", "A required super class {0} could not be found." },
{ "tracing.not.supported", "Warning: Tracing is no longer supported. Instead, use-verbose:jni option of the virtual machine." },
{ "tried.to.define.non.static", "Tried to generate #define for non-static field." },
{ "unknown.array.type", "An unknown array type encountered when generating old style headers." },
{ "unknown.option", "{0} is an illegal argument\n" },
{ "unknown.type.for.field", "An unknown type encountered when generating old style headers." },
{ "unknown.type.in.method.signature", "An unknown type eccountered when generating old style stubs." },
{ "usage", "Usage: javah [options] <classes>\n\nwhere [options] include:\n\n\t-help Print this help message and exit\n\t-classpath <path> Path from which to load classes\n\t-cp <path> Path from which to load classes\n\t-bootclasspath <path> Path from which to load bootstrap classes\n\t-d <dir> Output directory\n\t-o <file> Output file (only one of -d or -o may be used)\n\t-jni Generate JNI-style header file (default)\n\t-version Print version information\n\t-verbose Enable verbose output\n\t-force Always write output files\n\n<classes> are specified with their fully qualified names (for\ninstance, java.lang.Object).\n" },
};
}
}

View File

@@ -0,0 +1,58 @@
package com.sun.tools.javah.resources;
public final class l10n_ja extends java.util.ListResourceBundle {
protected final Object[][] getContents() {
return new Object[][] {
{ "at.args.cant.read", "\u30D5\u30A1\u30A4\u30EB{1}\u304B\u3089\u30B3\u30DE\u30F3\u30C9\u884C\u5F15\u6570\u3092\u8AAD\u307F\u8FBC\u3081\u307E\u305B\u3093\u3002" },
{ "at.args.file.not.found", "\u30D5\u30A1\u30A4\u30EB{0}\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002" },
{ "at.args.io.exception", "\u30B3\u30DE\u30F3\u30C9\u884C\u306E@\u5F15\u6570\u306E\u51E6\u7406\u4E2D\u306B\u3001\u6B21\u306E\u5165\u51FA\u529B\u306E\u554F\u984C\u304C\u767A\u751F\u3057\u307E\u3057\u305F: {0}\u3002" },
{ "cant.create.dir", "\u51FA\u529B\u7528\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u3092\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093\u3002" },
{ "class.not.found", "\u30AF\u30E9\u30B9{0}\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002" },
{ "dir.file.mixed", "\u30AA\u30D7\u30B7\u30E7\u30F3-d\u3068-o\u3092\u540C\u6642\u306B\u4F7F\u7528\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\u3002-help\u3067\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002" },
{ "encoding.iso8859_1.not.found", "\u51FA\u529B\u7528\u306EISO8859_1\u30B3\u30F3\u30D0\u30FC\u30BF\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u306B\u30A8\u30E9\u30FC\u304C\u3042\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002" },
{ "err.cant.use.option.for.fm", "\u6307\u5B9A\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u30FB\u30DE\u30CD\u30FC\u30B8\u30E3\u3067{0}\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093" },
{ "err.internal.error", "\u5185\u90E8\u30A8\u30E9\u30FC: {0}" },
{ "err.ioerror", "IO\u30A8\u30E9\u30FC: {0}" },
{ "err.missing.arg", "{0}\u306E\u5024\u304C\u3042\u308A\u307E\u305B\u3093" },
{ "err.no.classes.specified", "\u30AF\u30E9\u30B9\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093" },
{ "err.prefix", "\u30A8\u30E9\u30FC:" },
{ "err.unknown.option", "\u4E0D\u660E\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: {0}" },
{ "invalid.method.signature", "\u7121\u52B9\u306A\u30E1\u30BD\u30C3\u30C9\u30FB\u30B7\u30B0\u30CD\u30C1\u30E3: {0}" },
{ "io.exception", "\u30E1\u30C3\u30BB\u30FC\u30B8{0}\u306E\u5165\u51FA\u529B\u30A8\u30E9\u30FC\u304B\u3089\u56DE\u5FA9\u3067\u304D\u307E\u305B\u3093\u3002" },
{ "javah.fullVersion", "{0}\u30D5\u30EB\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3\"{1}\"" },
{ "javah.version", "{0}\u30D0\u30FC\u30B8\u30E7\u30F3\"{1}\"" },
{ "jni.llni.mixed", "\u30AA\u30D7\u30B7\u30E7\u30F3-jni\u3068-llni\u3092\u540C\u6642\u306B\u4F7F\u7528\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\u3002-help\u3067\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002" },
{ "jni.no.stubs", "JNI\u306F\u30B9\u30BF\u30D6\u3092\u5FC5\u8981\u3068\u3057\u307E\u305B\u3093\u3002JNI\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002" },
{ "jni.sigerror", "{0}\u306E\u30B7\u30B0\u30CD\u30C1\u30E3\u3092\u5224\u5225\u3067\u304D\u307E\u305B\u3093" },
{ "jni.unknown.type", "\u4E0D\u660E\u306A\u578B\u304C\u691C\u51FA\u3055\u308C\u307E\u3057\u305F(JNI)\u3002" },
{ "main.opt.bootclasspath", " -bootclasspath <path> \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9" },
{ "main.opt.classpath", " -classpath <path> \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9" },
{ "main.opt.cp", " -cp <path> \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9" },
{ "main.opt.d", " -d <dir> \u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA" },
{ "main.opt.force", " -force \u5E38\u306B\u51FA\u529B\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304D\u8FBC\u3080" },
{ "main.opt.h", " -h --help -? \u3053\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3059\u308B" },
{ "main.opt.jni", " -jni JNI\u5F62\u5F0F\u306E\u30D8\u30C3\u30C0\u30FC\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u751F\u6210\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)" },
{ "main.opt.o", " -o <file> \u51FA\u529B\u30D5\u30A1\u30A4\u30EB(-d\u304B-o\u306E\u3069\u3061\u3089\u304B\u4E00\u65B9\u3092\u4F7F\u7528\u3059\u308B)" },
{ "main.opt.v", " -v -verbose \u8A73\u7D30\u306A\u51FA\u529B\u3092\u884C\u3046" },
{ "main.opt.version", " -version \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\u3092\u51FA\u529B\u3059\u308B" },
{ "main.usage", "\u4F7F\u7528\u65B9\u6CD5: \n javah [options] <classes>\n[options]\u306B\u306F\u6B21\u306E\u3082\u306E\u304C\u3042\u308A\u307E\u3059\u3002" },
{ "main.usage.foot", "<classes>\u306F\u5B8C\u5168\u6307\u5B9A\u306E\u540D\u524D\u3067\u6307\u5B9A\u3057\u307E\u3059\n(java.lang.Object\u306A\u3069)\u3002" },
{ "no.bootclasspath.specified", "\u30B3\u30DE\u30F3\u30C9\u884C\u3067\u30D6\u30FC\u30C8\u30FB\u30AF\u30E9\u30B9\u30D1\u30B9\u304C\u6307\u5B9A\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F\u3002-help\u3067\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002" },
{ "no.classes.specified", "\u30B3\u30DE\u30F3\u30C9\u884C\u3067\u30AF\u30E9\u30B9\u304C\u6307\u5B9A\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F\u3002-help\u3067\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002" },
{ "no.classpath.specified", "\u30B3\u30DE\u30F3\u30C9\u884C\u3067\u30AF\u30E9\u30B9\u30D1\u30B9\u304C\u6307\u5B9A\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F\u3002-help\u3067\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002" },
{ "no.outputdir.specified", "\u30B3\u30DE\u30F3\u30C9\u884C\u3067\u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304C\u6307\u5B9A\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F\u3002-help\u3067\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002" },
{ "no.outputfile.specified", "\u30B3\u30DE\u30F3\u30C9\u884C\u3067\u51FA\u529B\u30D5\u30A1\u30A4\u30EB\u304C\u6307\u5B9A\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F\u3002-help\u3067\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002" },
{ "old.jni.mixed", "\u30AA\u30D7\u30B7\u30E7\u30F3-jni\u3068-old\u3092\u540C\u6642\u306B\u4F7F\u7528\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\u3002-help\u3067\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002" },
{ "old.llni.mixed", "\u30AA\u30D7\u30B7\u30E7\u30F3-old\u3068-llni\u3092\u540C\u6642\u306B\u4F7F\u7528\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\u3002-help\u3067\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002" },
{ "old.not.supported", "\u3053\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u306Ejavah\u3067\u306F\u30AA\u30D7\u30B7\u30E7\u30F3-old\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002" },
{ "super.class.not.found", "\u8981\u6C42\u3055\u308C\u305F\u30B9\u30FC\u30D1\u30FC\u30FB\u30AF\u30E9\u30B9{0}\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002" },
{ "tracing.not.supported", "\u8B66\u544A: \u30C8\u30EC\u30FC\u30B9\u306F\u73FE\u5728\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u304B\u308F\u308A\u306B\u3001Virtual Machine\u306E-verbose:jni\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002" },
{ "tried.to.define.non.static", "static\u3067\u306A\u3044\u30D5\u30A3\u30FC\u30EB\u30C9\u306B#define\u3092\u751F\u6210\u3057\u3088\u3046\u3068\u3057\u307E\u3057\u305F\u3002" },
{ "unknown.array.type", "\u53E4\u3044\u5F62\u5F0F\u306E\u30D8\u30C3\u30C0\u30FC\u3092\u751F\u6210\u3057\u3066\u3044\u308B\u3068\u304D\u306B\u4E0D\u660E\u306A\u914D\u5217\u306E\u578B\u304C\u691C\u51FA\u3055\u308C\u307E\u3057\u305F\u3002" },
{ "unknown.option", "{0}\u306F\u4E0D\u6B63\u306A\u5F15\u6570\u3067\u3059\n" },
{ "unknown.type.for.field", "\u53E4\u3044\u5F62\u5F0F\u306E\u30D8\u30C3\u30C0\u30FC\u3092\u751F\u6210\u3057\u3066\u3044\u308B\u3068\u304D\u306B\u4E0D\u660E\u306A\u578B\u304C\u691C\u51FA\u3055\u308C\u307E\u3057\u305F\u3002" },
{ "unknown.type.in.method.signature", "\u53E4\u3044\u5F62\u5F0F\u306E\u30B9\u30BF\u30D6\u3092\u751F\u6210\u3057\u3066\u3044\u308B\u3068\u304D\u306B\u4E0D\u660E\u306A\u578B\u304C\u691C\u51FA\u3055\u308C\u307E\u3057\u305F\u3002" },
{ "usage", "\u4F7F\u7528\u65B9\u6CD5: javah [options] <classes>\n\n[options]\u306B\u306F\u6B21\u306E\u3082\u306E\u304C\u3042\u308A\u307E\u3059\u3002\n\n\t-help \u30D8\u30EB\u30D7\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3057\u3066\u7D42\u4E86\u3059\u308B\n\t-classpath <path> \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9\n\t-cp <path> \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9\r\n\t-bootclasspath <path> \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9\n\t-d<dir> \u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\n\t-o <file> \u51FA\u529B\u30D5\u30A1\u30A4\u30EB(-d\u304B-o\u306E\u3069\u3061\u3089\u304B\u4E00\u65B9\u3092\u4F7F\u7528\u3059\u308B)\n\t-jni JNI\u5F62\u5F0F\u306E\u30D8\u30C3\u30C0\u30FC\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u751F\u6210\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)\n\t-version \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\u3092\u8868\u793A\u3059\u308B\n\t-verbose \u8A73\u7D30\u306A\u51FA\u529B\u3092\u884C\u3046\n\t-force \u5E38\u306B\u51FA\u529B\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304D\u8FBC\u3080\n\n<classes>\u306F\u5B8C\u5168\u6307\u5B9A\u306E\u540D\u524D\u3067\u6307\u5B9A\u3057\u307E\u3059\n(java.lang.Object\u306A\u3069)\u3002\n" },
};
}
}

View File

@@ -0,0 +1,58 @@
package com.sun.tools.javah.resources;
public final class l10n_zh_CN extends java.util.ListResourceBundle {
protected final Object[][] getContents() {
return new Object[][] {
{ "at.args.cant.read", "\u65E0\u6CD5\u4ECE\u6587\u4EF6{1}\u4E2D\u8BFB\u53D6\u547D\u4EE4\u884C\u53C2\u6570\u3002" },
{ "at.args.file.not.found", "\u627E\u4E0D\u5230\u6587\u4EF6{0}\u3002" },
{ "at.args.io.exception", "\u5904\u7406\u547D\u4EE4\u884C\u4E2D\u7684 @ \u53C2\u6570\u65F6, \u9047\u5230\u4EE5\u4E0B I/O \u95EE\u9898: {0}\u3002" },
{ "cant.create.dir", "\u65E0\u6CD5\u4E3A\u8F93\u51FA\u521B\u5EFA\u76EE\u5F55 {0}\u3002" },
{ "class.not.found", "\u627E\u4E0D\u5230\u7C7B{0}\u3002" },
{ "dir.file.mixed", "\u4E0D\u80FD\u6DF7\u7528\u9009\u9879 -d \u548C -o\u3002\u8BF7\u5C1D\u8BD5\u4F7F\u7528 -help\u3002" },
{ "encoding.iso8859_1.not.found", "\u627E\u4E0D\u5230\u7528\u4E8E\u8F93\u51FA\u7684 ISO8859_1 \u8F6C\u6362\u5668\u3002\u8FD9\u53EF\u80FD\u662F\u56E0\u4E3A\u5B89\u88C5\u8FC7\u7A0B\u4E2D\u51FA\u73B0\u4E86\u9519\u8BEF\u3002" },
{ "err.cant.use.option.for.fm", "\u4E0D\u80FD\u5C06{0}\u9009\u9879\u4E0E\u7ED9\u5B9A\u7684\u6587\u4EF6\u7BA1\u7406\u5668\u4E00\u8D77\u4F7F\u7528" },
{ "err.internal.error", "\u5185\u90E8\u9519\u8BEF: {0}" },
{ "err.ioerror", "IO \u9519\u8BEF: {0}" },
{ "err.missing.arg", "{0}\u7F3A\u5C11\u503C" },
{ "err.no.classes.specified", "\u672A\u6307\u5B9A\u7C7B" },
{ "err.prefix", "\u9519\u8BEF:" },
{ "err.unknown.option", "\u672A\u77E5\u9009\u9879: {0}" },
{ "invalid.method.signature", "\u65E0\u6548\u7684\u65B9\u6CD5\u7B7E\u540D: {0}" },
{ "io.exception", "\u65E0\u6CD5\u4ECE I/O \u9519\u8BEF\u4E2D\u6062\u590D, \u6D88\u606F\u4E3A: {0}\u3002" },
{ "javah.fullVersion", "{0}\u5B8C\u6574\u7248\u672C \"{1}\"" },
{ "javah.version", "{0}\u7248\u672C \"{1}\"" },
{ "jni.llni.mixed", "\u4E0D\u80FD\u6DF7\u7528\u9009\u9879 -jni \u548C -llni\u3002\u8BF7\u5C1D\u8BD5\u4F7F\u7528 -help\u3002" },
{ "jni.no.stubs", "JNI \u4E0D\u9700\u8981\u5B58\u6839, \u8BF7\u53C2\u9605 JNI \u6587\u6863\u3002" },
{ "jni.sigerror", "\u65E0\u6CD5\u786E\u5B9A{0}\u7684\u7B7E\u540D" },
{ "jni.unknown.type", "\u9047\u5230\u672A\u77E5\u7C7B\u578B (JNI)\u3002" },
{ "main.opt.bootclasspath", " -bootclasspath <path> \u4ECE\u4E2D\u52A0\u8F7D\u5F15\u5BFC\u7C7B\u7684\u8DEF\u5F84" },
{ "main.opt.classpath", " -classpath <path> \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84" },
{ "main.opt.cp", " -cp <path> \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84" },
{ "main.opt.d", " -d <dir> \u8F93\u51FA\u76EE\u5F55" },
{ "main.opt.force", " -force \u59CB\u7EC8\u5199\u5165\u8F93\u51FA\u6587\u4EF6" },
{ "main.opt.h", " -h --help -? \u8F93\u51FA\u6B64\u6D88\u606F" },
{ "main.opt.jni", " -jni \u751F\u6210 JNI \u6837\u5F0F\u7684\u6807\u5934\u6587\u4EF6 (\u9ED8\u8BA4\u503C)" },
{ "main.opt.o", " -o <file> \u8F93\u51FA\u6587\u4EF6 (\u53EA\u80FD\u4F7F\u7528 -d \u6216 -o \u4E4B\u4E00)" },
{ "main.opt.v", " -v -verbose \u542F\u7528\u8BE6\u7EC6\u8F93\u51FA" },
{ "main.opt.version", " -version \u8F93\u51FA\u7248\u672C\u4FE1\u606F" },
{ "main.usage", "\u7528\u6CD5: \n javah [options] <classes>\n\u5176\u4E2D, [options] \u5305\u62EC:" },
{ "main.usage.foot", "<classes> \u662F\u4F7F\u7528\u5176\u5168\u9650\u5B9A\u540D\u79F0\u6307\u5B9A\u7684\n(\u4F8B\u5982, java.lang.Object)\u3002" },
{ "no.bootclasspath.specified", "\u672A\u5728\u547D\u4EE4\u884C\u4E2D\u6307\u5B9A\u4EFB\u4F55\u5F15\u5BFC\u7C7B\u8DEF\u5F84\u3002\u8BF7\u5C1D\u8BD5\u4F7F\u7528 -help\u3002" },
{ "no.classes.specified", "\u672A\u5728\u547D\u4EE4\u884C\u4E2D\u6307\u5B9A\u4EFB\u4F55\u7C7B\u3002\u8BF7\u5C1D\u8BD5\u4F7F\u7528 -help\u3002" },
{ "no.classpath.specified", "\u672A\u5728\u547D\u4EE4\u884C\u4E2D\u6307\u5B9A\u4EFB\u4F55\u7C7B\u8DEF\u5F84\u3002\u8BF7\u5C1D\u8BD5\u4F7F\u7528 -help\u3002" },
{ "no.outputdir.specified", "\u672A\u5728\u547D\u4EE4\u884C\u4E2D\u6307\u5B9A\u4EFB\u4F55\u8F93\u51FA\u76EE\u5F55\u3002\u8BF7\u5C1D\u8BD5\u4F7F\u7528 -help\u3002" },
{ "no.outputfile.specified", "\u672A\u5728\u547D\u4EE4\u884C\u4E2D\u6307\u5B9A\u4EFB\u4F55\u8F93\u51FA\u6587\u4EF6\u3002\u8BF7\u5C1D\u8BD5\u4F7F\u7528 -help\u3002" },
{ "old.jni.mixed", "\u4E0D\u80FD\u6DF7\u7528\u9009\u9879 -jni \u548C -old\u3002\u8BF7\u5C1D\u8BD5\u4F7F\u7528 -help\u3002" },
{ "old.llni.mixed", "\u4E0D\u80FD\u6DF7\u7528\u9009\u9879 -old \u548C -llni\u3002\u8BF7\u5C1D\u8BD5\u4F7F\u7528 -help\u3002" },
{ "old.not.supported", "\u6B64\u7248\u672C\u7684 javah \u4E0D\u652F\u6301\u9009\u9879 -old\u3002" },
{ "super.class.not.found", "\u627E\u4E0D\u5230\u6240\u9700\u7684\u8D85\u7C7B{0}\u3002" },
{ "tracing.not.supported", "\u8B66\u544A: \u4E0D\u518D\u652F\u6301\u8DDF\u8E2A\u3002\u8BF7\u4F7F\u7528\u865A\u62DF\u673A\u7684 -verbose:jni \u9009\u9879\u3002" },
{ "tried.to.define.non.static", "\u5C1D\u8BD5\u4E3A\u975E\u9759\u6001\u5B57\u6BB5\u751F\u6210 #define\u3002" },
{ "unknown.array.type", "\u751F\u6210\u65E7\u6837\u5F0F\u7684\u6807\u5934\u65F6\u9047\u5230\u672A\u77E5\u7684\u6570\u7EC4\u7C7B\u578B\u3002" },
{ "unknown.option", "{0}\u662F\u975E\u6CD5\u53C2\u6570\n" },
{ "unknown.type.for.field", "\u751F\u6210\u65E7\u6837\u5F0F\u7684\u6807\u5934\u65F6\u9047\u5230\u672A\u77E5\u7684\u7C7B\u578B\u3002" },
{ "unknown.type.in.method.signature", "\u751F\u6210\u65E7\u6837\u5F0F\u7684\u5B58\u6839\u65F6\u9047\u5230\u672A\u77E5\u7684\u7C7B\u578B\u3002" },
{ "usage", "\u7528\u6CD5: javah [options] <classes>\n\n\u5176\u4E2D, [options] \u5305\u62EC:\n\n\t-help \u8F93\u51FA\u6B64\u5E2E\u52A9\u6D88\u606F\u5E76\u9000\u51FA\n\t-classpath <path> \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84\n\t-cp <path> \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84\n\t-bootclasspath <path> \u4ECE\u4E2D\u52A0\u8F7D\u5F15\u5BFC\u7C7B\u7684\u8DEF\u5F84\n\t-d <dir> \u8F93\u51FA\u76EE\u5F55\n\t-o <file> \u8F93\u51FA\u6587\u4EF6 (\u53EA\u80FD\u4F7F\u7528 -d \u6216 -o \u4E4B\u4E00)\n\t-jni \u751F\u6210 JNI \u6837\u5F0F\u7684\u6807\u5934\u6587\u4EF6 (\u9ED8\u8BA4\u503C)\n\t-version \u8F93\u51FA\u7248\u672C\u4FE1\u606F\n\t-verbose \u542F\u7528\u8BE6\u7EC6\u8F93\u51FA\n\t-force \u59CB\u7EC8\u5199\u5165\u8F93\u51FA\u6587\u4EF6\n\n<classes> \u662F\u4F7F\u7528\u5176\u5168\u9650\u5B9A\u540D\u79F0\u6307\u5B9A\u7684,\n(\u4F8B\u5982, java.lang.Object)\u3002\n" },
};
}
}

View File

@@ -0,0 +1,11 @@
package com.sun.tools.javah.resources;
public final class version extends java.util.ListResourceBundle {
protected final Object[][] getContents() {
return new Object[][] {
{ "full", "1.8.0_462-b08" },
{ "jdk", "1.8.0_462" },
{ "release", "1.8.0_462" },
};
}
}