简体   繁体   中英

Reconstructing an Executable jar (with Modified Class-Path) from Class Files

I'm grading an assignment in Java. Students are asked to implement a Five-In-A-Row (like Tic-Tac-Toe, or two-player Pente) interface which is used by a GUI .java file. These files (interface and GUI) are given to the students in a file called lab2.jar (where they're in cs251/lab2/ under the names GomokuModel and GomokuGUI , respectively), which the students must add to their classpaths. When the project is finished, students are requested to turn in a .java file called Gomoku.java.

One student turned in a .jar, but the command

java -jar Gomoku.jar 

responds with

no main manifest attribute, in Gomoku.jar

I figure the student may have forgotten / not known to make a manifest file. I unzip the student's jar and find only .class files. I try to make my own jar from these files:

According to specs, the main must be in Gomoku.java, whose class is Gomoku.class. So I make a manifest.txt file that looks like

Main-Class: Gomoku
Class-Path: lab2.jar

And try to make a .jar out of it using the command

jar cfm myJar.jar manifest.txt *.class lab2.jar

But when I run this using the command

java -jar myJar.jar

I get the following error:

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)

This particular error is giving me trouble. I've never seen anything like it, and my research on the web doesn't turn up anything. Because the error says it's coming from GomokuGUI, which is one of the lab2.jar files, I think the error's on my end. My questions are:

  1. Can I make an executable .jar when I know and have

    • What goes in the classpath
    • Where the main should be
    • A set of relevant class files
  2. If the answer to (1) is yes: Am I going about it in the right way? I have a feeling I'm missing a recompile step somewhere.

In this particular case, I may ask the student to resubmit. And I will download the .jar's I see submitted before due date to make sure they are runnable. But for knowledge's sake (I myself have made .jar files that have had only .class in them and no manifest), is there a way to salvage a working file like the one described above?

From the JRE javadoc:

public class IllegalAccessError extends IncompatibleClassChangeError

Thrown if an application attempts to access or modify a field, or to call a method that it does not have access to.

You're getting

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)

The method it's complaining about is named <init> . That's what Java calls constructors, internally. It's saying that Gomoku.main() tried to issue new GomokuGUI(model) where model is expected to be an instance of GomokuModel, but that this constructor was not accessible. The fact that Gomoku.main() is in a different package from GomokuGUI means the constructor would have to be public for that to work.

You can check that via reflection -- I believe Eclipse can do that for you, actually -- but that's almost certainly what's going on.

So either the student turned in broken code, or you broke it during your attempts to force-fit it into convenience-executable jarfile format. Which was wasted effort in any case, since you can't grade the assignment based on object code and you're going to have to go back and ask for source code anyway.

If you really want to try running the jarfile the student submitted: Go back to the original unmodified jarfile and try just running 'java Gomoku -classpath myJar.jar' where myJar.jar is what the student turned in. If that doesn't work, try 'java Lcs251.lab2.Gomoku -classpath myJar.jar', which is probably the package they intended to put it into given the error message you're getting. If neither of those runs, ask the student what command line they've been using to run it and try that. If THAT doesn't work, then it's time to investigate why.

The whole executable-jar question is a red herring and a waste of time until you know the code actually runs and what the entry point actually is.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM