从类文件重建可执行jar(带有修改的类路径)

时间:2014-02-22 23:58:44

标签: java

我正在用Java评分作业。要求学生实现GUI .java文件使用的Five-In-A-Row(如Tic-Tac-Toe或双人Pente)界面。这些文件(界面和GUI)将在名为lab2.jar的文件中提供给学生(其中cs251/lab2/分别位于名称GomokuModelGomokuGUI下),其中学生必须添加到他们的课程路径。项目完成后,要求学生上交一个名为Gomoku.java的.java文件。

一名学生上了一个.jar,但命令

java -jar Gomoku.jar 

回应
  

在Gomoku.jar

中没有主要的清单属性

我认为学生可能已经忘记/不知道制作清单文件。我unzip学生的jar并且只找到.class文件。我尝试用这些文件制作自己的jar:

根据规范,主要必须在Gomoku.java中,其类是Gomoku.class。所以我创建了一个看起来像

的manifest.txt文件
Main-Class: Gomoku
Class-Path: lab2.jar

尝试使用命令

制作一个.jar
jar cfm myJar.jar manifest.txt *.class lab2.jar

但是当我使用命令

运行时
java -jar myJar.jar

我收到以下错误:

0Exception in thread "main" java.lang.IllegalAccessError: tried to access method cs251.lab2.GomokuGUI.<init>(Lcs251/lab2/GomokuModel;)V from class Gomoku
    at Gomoku.main(Gomoku.java:47)

这个特殊的错误给了我麻烦。我从来没有见过这样的东西,我在网上的研究也没有发现任何东西。因为错误说它来自GomokuGUI,这是lab2.jar文件之一,我认为错误就在我的最后。我的问题是:

  1. 我知道并且

    时可以创建可执行文件.jar
    • 类路径中的内容
    • 主要应该在哪里
    • 一组相关的类文件
  2. 如果(1)的答案是肯定的:我是否以正确的方式解决这个问题?我有一种感觉,我错过了重新编译步骤。

  3. 在这种特殊情况下,我可能会要求学生重新提交。我将在截止日期之前下载提交的.jar,以确保它们可以运行。但是出于知识的考虑(我自己制作了.jar文件,其中只包含.class而没有清单),有没有办法挽救像上面描述的那样的工作文件?

1 个答案:

答案 0 :(得分:0)

来自JRE javadoc:

  

public class IllegalAccessError   扩展IncompatibleClassChangeError

     

如果应用程序尝试访问或修改字段,则抛出   调用一个它无权访问的方法。

你得到了

0Exception in thread "main" java.lang.IllegalAccessError: tried to access method
cs251.lab2.GomokuGUI.<init>(Lcs251/lab2/GomokuModel;)V from class Gomoku
    at Gomoku.main(Gomoku.java:47)

它抱怨的方法名为<init>。这就是Java在内部调用构造函数的原因。它说Gomoku.main()试图发出new GomokuGUI(model),其中模型应该是GomokuModel的一个实例,但是这个构造函数是不可访问的。事实上,Gomoku.main()与GomokuGUI位于不同的包中,这意味着构造函数必须是公共的才能使其工作。

你可以通过反思来检查 - 我相信Eclipse可以为你做到这一点,实际上 - 但这几乎肯定是正在发生的事情。

因此,要么学生拒绝破解代码,要么在尝试将其强制插入便利可执行jarfile格式时将其破坏。这在任何情况下都是浪费精力,因为您无法根据目标代码对作业进行评分,并且您将不得不返回并询问源代码。

如果你真的想尝试运行学生提交的jar文件:回到原始未经修改的jar文件并尝试运行'java Gomoku -classpath myJar.jar',其中myJar.jar是学生上交的。如果没有工作,尝试'java Lcs251.lab2.Gomoku -classpath myJar.jar',这可能是他们打算把它放入的包,给出你得到的错误信息。如果这两个都没有运行,请询问学生他们用来运行它的命令行并试一试。如果这不起作用,那么就该调查原因了。

整个可执行jar问题是一个红色的鲱鱼,浪费时间,直到你知道代码实际运行以及入口点实际上是什么。