这是因为在JProtobuf 源码里面使用到系统JDK编译器:
public JdkCompiler(final ClassLoader loader, String jdkVersion) {
this.compiler = ToolProvider.getSystemJavaCompiler();
this.options = new ArrayList();
this.options.add("-source");
this.options.add(jdkVersion);
this.options.add("-target");
this.options.add(jdkVersion);
if (this.compiler == null) {
throw new RuntimeException("compiler is null maybe you are on JRE enviroment please change to JDK enviroment.");
} else {
DiagnosticCollector<JavaFileObject> diagnosticCollector = new DiagnosticCollector();
StandardJavaFileManager manager = this.compiler.getStandardFileManager(diagnosticCollector, (Locale)null, (Charset)null);
if (loader instanceof URLClassLoader && !loader.getClass().getName().equals("sun.misc.Launcher$AppClassLoader")) {
try {
URLClassLoader urlClassLoader = (URLClassLoader)loader;
List<File> files = new ArrayList();
URL[] arr$ = urlClassLoader.getURLs();
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; ++i$) {
URL url = arr$[i$];
String file = url.getFile();
if (StringUtils.endsWith(file, "!/")) {
file = StringUtils.removeEnd(file, "!/");
}
if (file.startsWith("file:")) {
file = StringUtils.removeStart(file, "file:");
}
files.add(new File(file));
}
manager.setLocation(StandardLocation.CLASS_PATH, files);
} catch (IOException var12) {
throw new IllegalStateException(var12.getMessage(), var12);
}
}
this.classLoader = (JdkCompiler.ClassLoaderImpl)AccessController.doPrivileged(new PrivilegedAction<JdkCompiler.ClassLoaderImpl>() {
public JdkCompiler.ClassLoaderImpl run() {
return JdkCompiler.this.new ClassLoaderImpl(loader);
}
});
this.javaFileManager = new JdkCompiler.JavaFileManagerImpl(manager, this.classLoader);
}
}
使用java -jar 命令运行jar的时候,会默认选择jre环境下的lib下的tool.jar进行编译,所以,解决方法是:
将 jdk1.8.0_131/lib 下的 tool.jar 复制到 jre1.8.0_131/lib 下,即可解决。
启动服务器时,读取配置文件方法是静态方法,这是在运行main方法之前就会执行的,配置服务器是在main方法执行的,所以会出现没有读取配置文件的问题。
解决方法是:
1,将配置文件读取换做静态方法
或者
2,将配置服务器方法换到init里面,作为单例执行