简体   繁体   中英

Print Class-Content to Console in java

I'm trying to make a little program from school better, because I am more advanced then the others in my class and want to have a bit fun. It is a simple command line program in java but I want to make it with a full GUI.

So basically I want to access the JAR-File when executed and print the code written in a (by menu selected) class-file. I already know how to find the JAR-File and this works, but I can't find any way to get INTO the JAR-File. I tried creating a File object and putting the path to the JAR combined with the path to the class file I want to access. (Ex: "C:\temp\Test\program.jar\de\bbzsogr\Main.class" as found in WinRAR)

Here is some Code of the "CodeGrabber" class i wrote to access the JAR and then the file in the JAR.


public class CodeGrabber {

    private static File JAR;

    public static void grabCode(String className) {

        try {
            JAR = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }

        System.out.println("JAR is located in: " + JAR);

        // -> "JAR is located in: C:\temp\Test.jar"

        System.out.println("Searching for \"" + JAR + File.separator + "ch" + File.separator + "bbzsogr" + File.separator + "Main.class");

        // -> "Searching for "C:\temp\Test.jar\ch\bbzsogr\Main.class" "

        File main = new File(JAR + File.separator + "ch" + File.separator + "bbzsogr" + File.separator + "Main.class");

        try {
            Scanner scanner = new Scanner(main);

            while(scanner.hasNext()) {
                System.out.println(scanner.nextLine());
            }
        } catch (FileNotFoundException e) {
            System.out.println("File MAIN not found...");
            return;
        }

        // -> "File MAIN not found..."

    }

}


I excepted to get a scrambled mess of data because the file, if I could access it, is still encoded/compiled, but I get the Message, that the wanted file was not found.

Thanks in advance!!

If you want to add and access a jar file inside a java program,you must import the java classes this jar contains and use their methods.You should write something like import prog.mainclass at the beginning of your program rather than trying to access it through the Jar.

For what you are asking now,the reason your program can't find the jar is because the path you imported is not valid.Java can't search inside any program but only inside a filesystem.Any path should be without dots like C:/temp/path and can't be,for example C:/temp.csv/path

TLDR: jar entries are not files.

A jar file is a file -- note 'a' meaning 'one'. A jar file is typically created by taking several files (often as many as hundreds, thousands, or more), usually at least some of them java (compiled) class files, (usually) compressing the data from each one, and writing the (compressed) data and name for each file as an entry in the jar. It is possible however for a jar entry not to come from a file; for example the manifest entry is often created 'on the fiy' rather than read from a file, and for a signed jar the signature entries always are. But even for jar entries that are created from files, the jar entries themselves are not files, and cannot be accessed as files using basic pre-NIO file access.

You have three options.

  1. For a jar in the classpath -- which your jar obviously is, since you found it as the source for a loaded class, ClassLoader allows you to read any entry as a 'resource'. This is normally used for things like images, audio, video or other data packed in a jar with an application, but it works on entries that are class files.
    // you can invoke it based on a known class like
    InputStream is = Main.class.getResourceAsStream("path/for/package/Foo.class");
    // or globally
    InputStream is = ClassLoader.getResourceAsStream("path/for/package/Foo.class");
  1. jar files are really zip files 'underneath', and Java has long allowed you to access zip files using java.io.ZipFile (directly) or java.io.ZipInputStream (layered on a FileInputStream ). The former allows you to access entries 'randomly' using the so-called central directory, while the latter requires you to access entries in the order they occur in the file (and works on nonseekable underlying file forms like pipes and socket connections, but you don't need that here) which makes it a little less convenient for your purpose but still workable. See the javadoc for either.

  2. NIO in Java 7 up (and pretty much everybody should be there by now) adds support for alternate filesystems which provide file-like (or at least stream-like) access to things other than actual files supported by the underlying operating system or its file system(s). And although more can be added, it comes with one alternate provider already installed which handles jars (really zips) -- just as you want.

    String jarname = Main.class.getProtectionDomain().getCodeSource().getLocation().getPath();
    FileSystem fs = FileSystems.newFileSystem(Paths.get(jarname), null);
    InputStream is = Files.newInputStream(fs.getPath("package/Foo.class"));

Note that in all cases I've opened an InputStream, not a Reader (or Scanner). Reader and Scanner are for text consisting of characters, and in most cases lines (which by definition contain characters). Class files have some characters here and there, but are mostly not characters and thus not text; they need to be read and processed as binary (with the few parts that are characters converted if desired). Have fun.

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