我正在从字符串编译Java类,但是由于某种原因,我在Windows上可以正常工作,但在Linux上抛出NullPointerException。
我已经尝试使用Google搜索找到一种解决方案,但是甚至找不到与此远程相关的内容。
这是堆栈跟踪:
java.lang.RuntimeException: java.lang.NullPointerException
at com.sun.tools.javac.main.Main.compile(Main.java:559)
at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138) //This is where the compiler task gets called
at mekanism.common.network.PacketSecurityUpdate.invalidUsername(PacketSecurityUpdate.java:140)
at mekanism.common.network.PacketSecurityUpdate$SecurityUpdateMessage.fromBytes(PacketSecurityUpdate.java:89)
at cpw.mods.fml.common.network.simpleimpl.SimpleIndexedCodec.decodeInto(SimpleIndexedCodec.java:17)
at cpw.mods.fml.common.network.simpleimpl.SimpleIndexedCodec.decodeInto(SimpleIndexedCodec.java:7)
at cpw.mods.fml.common.network.FMLIndexedMessageToMessageCodec.decode(FMLIndexedMessageToMessageCodec.java:77)
at cpw.mods.fml.common.network.FMLIndexedMessageToMessageCodec.decode(FMLIndexedMessageToMessageCodec.java:17)
at io.netty.handler.codec.MessageToMessageCodec$2.decode(MessageToMessageCodec.java:81)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:89)
at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337)
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785)
at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:169)
at cpw.mods.fml.common.network.internal.FMLProxyPacket.func_148833_a(FMLProxyPacket.java:77)
at net.minecraft.network.NetworkManager.func_74428_b(NetworkManager.java:245)
at net.minecraft.network.NetworkSystem.func_151269_c(NetworkSystem.java:181)
at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:1023)
at net.minecraft.server.dedicated.DedicatedServer.func_71190_q(DedicatedServer.java:432)
at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:841)
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:693)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
at com.sun.tools.javac.api.ClientCodeWrapper.isTrusted(ClientCodeWrapper.java:189)
at com.sun.tools.javac.api.ClientCodeWrapper.wrap(ClientCodeWrapper.java:133)
at com.sun.tools.javac.api.ClientCodeWrapper$WrappedJavaFileManager.getJavaFileForOutput(ClientCodeWrapper.java:309)
at com.sun.tools.javac.jvm.ClassWriter.writeClass(ClassWriter.java:1615)
at com.sun.tools.javac.main.JavaCompiler.genCode(JavaCompiler.java:746)
at com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1572)
at com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1536)
at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:901)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:860)
at com.sun.tools.javac.main.Main.compile(Main.java:523)
... 23 more
这是我正在使用的代码
public static final JavaCompiler JAVAC;
static {
String h = System.getProperty("java.home");
if (!h.endsWith("jre")) {
h = h.replace("jre", "jdk") + File.separator + "jre";
System.setProperty("java.home", h);
}
System.out.println(System.getProperty("java.home"));
JAVAC = ToolProvider.getSystemJavaCompiler();
}
public static class JavaClass extends SimpleJavaFileObject {
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
public JavaClass(String className) {
super(getUri(className), Kind.CLASS);
}
private static final URI getUri(String className) {
try {
return new URI(className);
} catch (URISyntaxException e) {
throw new RuntimeException("Could not parse URI", e);
}
}
@Override
public OutputStream openOutputStream() throws IOException {
return baos;
}
public byte[] getByteCode() {
return baos.toByteArray();
}
}
public static class JavaClassLoader extends ClassLoader {
private final Map<String, JavaClass> classes = new HashMap<>();
public JavaClassLoader(ClassLoader classLoader) {
super(classLoader);
}
public JavaClass getClass(String name) {
return classes.get(name);
}
public JavaClassLoader addClass(JavaClass cc) {
classes.put(cc.getName(), cc);
return this;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
JavaClass cc = classes.get(name);
if (cc == null) {
return super.findClass(name);
}
byte[] byteCode = cc.getByteCode();
return defineClass(name, byteCode, 0, byteCode.length);
}
}
public static class FileManager extends ForwardingJavaFileManager<JavaFileManager> {
private static final StandardJavaFileManager STANDARD_JAVA_FILE_MANAGER = JAVAC.getStandardFileManager(null, null, null);
private JavaClassLoader classLoader = new JavaClassLoader(Test.class.getClassLoader());
public FileManager(String className) {
super(STANDARD_JAVA_FILE_MANAGER);
this.classLoader.addClass(new JavaClass(className));
}
public JavaClassLoader getClassLoader() {
return classLoader;
}
@Override
public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException {
return classLoader.getClass(className);
}
public byte[] getBytecode(String className) {
return classLoader.getClass(className).getByteCode();
}
public Class<?> loadClass(String className) throws ClassNotFoundException {
return classLoader.loadClass(className);
}
}
public static class JavaSource extends SimpleJavaFileObject {
private final String code;
public JavaSource(String name, String code) {
super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
public static void main(String[] args) throws Exception {
String className = //Class name
String code = //Code
JavaSource sourceCode = new JavaSource(className, code);
FileManager fileManager = new FileManager(className);
JAVAC.getTask(null, fileManager, null, null, null, Arrays.asList(sourceCode)).call();
}
答案 0 :(得分:0)
@MadProgrammer的评论使我意识到自己忘记了什么。 Java home修复程序仅在Windows上相关
static {
if (System.getProperty("os.name").toLowerCase().contains("windows")) { //Added this check
String h = System.getProperty("java.home");
if (!h.endsWith("jre")) {
h = h.replace("jre", "jdk") + File.separator + "jre";
System.setProperty("java.home", h);
}
}
JAVAC = ToolProvider.getSystemJavaCompiler();
}