jvm - 有没有办法软更改 Java 版本?
问题描述
我有一个旧应用程序拒绝在未经测试的 Java 版本上启动。不幸的是,它是一个废弃软件,因此几乎没有机会对其进行更新。它抱怨JVM是由Oracle而不是Sun制造的。
在 MS DOS 的日子里,有一个setver
命令允许设置应用程序看到的操作系统版本,有没有类似于 JVM 上的东西?
解决方案
我将使用 OpenJDK 项目中的asmtools将文件反汇编为字节码汇编格式。例如,一个 helloworld 看起来像这样 ( jdis NameOfClass.class>NameOfClass.j
):
super public class A
version 59:0
{
public Method "<init>":"()V"
stack 1 locals 1
{
aload_0;
invokespecial Method java/lang/Object."<init>":"()V";
return;
}
public static Method main:"([Ljava/lang/String;)V"
stack 2 locals 1
{
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
ldc String "Hello World!";
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
return;
}
} // end Class A
之后,您编辑文件:
super public class A
version 59:0
{
public Method "<init>":"()V"
stack 1 locals 1
{
aload_0;
invokespecial Method java/lang/Object."<init>":"()V";
return;
}
public static Method main:"([Ljava/lang/String;)V"
stack 2 locals 1
{
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
ldc String "Hello Stackoverflow!";
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
return;
}
} // end Class A
然后您可以再次将其编译为 .class :
jasm NameOfClass.j
然后就可以用Java正常运行了。
这只是一个例子。
您只需要使用检查版本的方法找到类。例如,您可以解压缩 jar 文件,如果不匹配版本的消息是,例如:
“检测到错误版本:”
你可以只用 grep (grep -R Bad.version
)然后你就可以上课了。在那里,您将不得不更改负责检查 Java 版本的方法。
一个例子:
A.java:
public class A{
static boolean hasMatchingJavaVersion() {
return System.getProperty("java.version").matches("1.4.*");//Just Java 1.4
}
public static void main(String[] args) {
if(hasMatchingJavaVersion()) {
System.out.println("Matches");
} else {
System.out.println("Bad version");
System.exit(-1);
}
}
}
运行它:(false
在 Java 15 上,例如)
作为组装。
super public class A
version 59:0
{
public Method "<init>":"()V"
stack 1 locals 1
{
aload_0;
invokespecial Method java/lang/Object."<init>":"()V";
return;
}
static Method hasMatchingJavaVersion:"()Z"
stack 2 locals 0
{
ldc String "java.version";
invokestatic Method java/lang/System.getProperty:"(Ljava/lang/String;)Ljava/lang/String;";
ldc String "1.4.*";
invokevirtual Method java/lang/String.matches:"(Ljava/lang/String;)Z";
ireturn;
}
public static Method main:"([Ljava/lang/String;)V"
stack 2 locals 1
{
invokestatic Method hasMatchingJavaVersion:"()Z";
ifeq L17;
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
ldc String "Matches";
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
goto L29;
L17: stack_frame_type same;
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
ldc String "Bad version";
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
iconst_m1;
invokestatic Method java/lang/System.exit:"(I)V";
L29: stack_frame_type same;
return;
}
} // end Class A
此方法检查版本:
static Method hasMatchingJavaVersion:"()Z"
stack 2 locals 0
{
ldc String "java.version";
invokestatic Method java/lang/System.getProperty:"(Ljava/lang/String;)Ljava/lang/String;";
ldc String "1.4.*";
invokevirtual Method java/lang/String.matches:"(Ljava/lang/String;)Z";
ireturn;
}
因此,您可以例如将其更改为:
static Method hasMatchingJavaVersion:"()Z"
stack 2 locals 0
{
iconst_1;//Load true, always return true
ireturn;
}
然后用jasm
.
编辑:
JVM 是由 Oracle 而不是 Sun 制造的。
我过度阅读了这个,但它的工作方式与上述相同,只是另一个系统属性和一些其他小的变化,
推荐阅读
- python - 类型错误:tokenize_lemmatize_spacy() 缺少 1 个必需的位置参数:'first_arg'
- python - sqlalchemy NullPool 似乎没有关闭底层 DBAPI 连接
- c# - C#好奇切换数字
- iphone - 如何解决 iPhone 中“Command /bin/sh failed with exit code 2”的问题?
- woocommerce - Woocommerce - 将自定义字段添加到结帐和自定义仪表板选项卡
- python - 根据条件向 pandas df 添加新列
- django - 为什么 django 不需要所有字段来测试模型
- node.js - 如何在 NodeJS 中的 URL 中传递变量
- php - 如何使用 guzzle 为基本身份验证发送正确的授权标头
- python - Python - 通过传递多个参数从 sqlite 表中选择