diff --git a/src/com/gabongao/jvm/Cmd.java b/src/com/gabongao/jvm/Cmd.java index 24c9179..7e2099c 100644 --- a/src/com/gabongao/jvm/Cmd.java +++ b/src/com/gabongao/jvm/Cmd.java @@ -32,7 +32,7 @@ public class Cmd { boolean versionFlag = false; String cpOption = ""; String className = ""; - String Xjre = ""; + String jreOption = ""; String[] args; /** @@ -60,8 +60,8 @@ public class Cmd { return args; } - public String getXjre() { - return Xjre; + public String getJreOption() { + return jreOption; } /** @@ -73,7 +73,7 @@ public class Cmd { this.cpOption = ""; this.className = ""; this.args = null; - this.Xjre = ""; + this.jreOption = ""; } /** @@ -88,7 +88,7 @@ public class Cmd { options.addOption("version", false, "print version and exit"); options.addOption("?", "help", false, "print help message"); options.addOption("cp", "classpath", true, "classpath"); - options.addOption("Xjre", true, "path to jre"); + options.addOption("jreOption", true, "path to jre"); CommandLine commandLine = parser.parse(options, args); if (commandLine.hasOption("help") || commandLine.hasOption("?")) { this.helpFlag = true; @@ -103,8 +103,8 @@ public class Cmd { this.cpOption = commandLine.getOptionValue("classpath"); } - if (commandLine.hasOption("Xjre")) { - this.Xjre = commandLine.getOptionValue("Xjre"); + if (commandLine.hasOption("jreOption")) { + this.jreOption = commandLine.getOptionValue("jreOption"); } String[] commandLineArgs = commandLine.getArgs(); if (commandLineArgs.length > 0) { diff --git a/src/com/gabongao/jvm/Jvm.java b/src/com/gabongao/jvm/Jvm.java index ecee8fe..277b944 100644 --- a/src/com/gabongao/jvm/Jvm.java +++ b/src/com/gabongao/jvm/Jvm.java @@ -1,5 +1,8 @@ package com.gabongao.jvm; +import com.gabongao.jvm.classpath.ClassPath; + +import java.io.File; import java.util.Arrays; /** @@ -39,6 +42,22 @@ public class Jvm { } } private static void startJvm(Cmd cmd) { + /* ch01 System.out.printf("classpath: %s class: %s args:%s\n", cmd.getCpOption(), cmd.getClassName(), Arrays.asList(cmd.getArgs()).toString()); + */ + + ClassPath cp = new ClassPath(); + cp.parse(cmd.jreOption, cmd.cpOption); + System.out.printf("classpath: %s\tclass: %s\targs: %s\n",cmd.cpOption,cmd.className, Arrays.asList(cmd.args)); + String className = cmd.className.replace(".", "/").concat(".class"); + byte[] classData = cp.readClass(className); + if (classData == null) { + System.out.printf("Could not load main class %s\n",className); + System.exit(1); + } + for (byte b:classData + ) { + System.out.printf("%X",b); + } } } diff --git a/src/com/gabongao/jvm/classpath/ClassPath.java b/src/com/gabongao/jvm/classpath/ClassPath.java new file mode 100644 index 0000000..8b601cb --- /dev/null +++ b/src/com/gabongao/jvm/classpath/ClassPath.java @@ -0,0 +1,89 @@ +package com.gabongao.jvm.classpath; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; + +/** + *         ┏┓   ┏┓+ + + *        ┏┛┻━━━┛┻┓ + + + *        ┃       ┃ + *        ┃   ━   ┃ ++ + + + + *        ████━████ ┃+ + *        ┃       ┃ + + *        ┃   ┻   ┃ + *        ┃       ┃ + + + *        ┗━┓   ┏━┛ + *          ┃   ┃ + *          ┃   ┃ + + + + + *          ┃   ┃    Code is far away from bug with the animal protecting + *          ┃   ┃ +     神兽保佑,代码无bug + *          ┃   ┃ + *          ┃   ┃  + + *          ┃    ┗━━━┓ + + + *          ┃        ┣┓ + *          ┃        ┏┛ + *          ┗┓┓┏━┳┓┏┛ + + + + + *           ┃┫┫ ┃┫┫ + *           ┗┻┛ ┗┻┛+ + + + + * Created by Imgaojp on 2017/2/17. + */ +public class ClassPath { + public Entry bootClasspath; + public Entry extClasspath; + public Entry userClasspath; + + public void parse(String jreOption,String cpOption) { + parseBootAndExtClasspath(jreOption); + parseUserClasspath(cpOption); + } + + public byte[] readClass(String className) { + byte[] bytes = bootClasspath.readClass(className); + if ( bytes!= null) { + return bytes; + } + bytes = extClasspath.readClass(className); + if (bytes != null) { + return bytes; + } + return userClasspath.readClass(className); + } + + public void parseUserClasspath(String cpOption) { + if (cpOption == "") { + cpOption = "."; + } + userClasspath = Entry.newEntry(cpOption); + } + + public void parseBootAndExtClasspath(String jreOption) { + String jreDir = ""; + String env = System.getenv("JAVA_HOME"); + if (jreOption != "" && exists(jreOption)) { + jreDir = jreOption; + } else if (exists("./jre")) { + jreDir = "./jre"; + } else if (env != "") { + jreDir = env.concat(File.separatorChar + "jre"); + } else { + throw new RuntimeException("can't find jre folder"); + } + // jre/lib/* + String jreLibPath = jreDir.concat(File.separatorChar + "lib" + File.separatorChar + "*"); + bootClasspath = Entry.newEntry(jreLibPath); + + // jre/lib/ext/* + String jreExtPath = jreDir.concat(File.separatorChar + "lib" + File.separatorChar + "ext" + File.separatorChar + "*"); + extClasspath = Entry.newEntry(jreExtPath); + } + + private boolean exists(String path) { + return new File(path).exists(); + } + + @Override + public String toString() { + return userClasspath.toString(); + } +} diff --git a/src/com/gabongao/jvm/classpath/Entry.java b/src/com/gabongao/jvm/classpath/Entry.java index 147d849..12a9192 100644 --- a/src/com/gabongao/jvm/classpath/Entry.java +++ b/src/com/gabongao/jvm/classpath/Entry.java @@ -28,12 +28,12 @@ public abstract class Entry { static String pathListSeparator = System.getProperty("path.separator");//system path separator public static Entry newEntry(String path) { -// if (path.contains(pathListSeparator)) { -// return newCompositeEntry(path); -// } -// if (path.contains("*")) { -// return new WildcardEntry(path); -// } + if (path.contains(pathListSeparator)) { + return new Entry_Composite(path); + } + if (path.contains("*")) { + return new Entry_Wildcard(path); + } if (path.contains(".jar") || path.contains(".zip") || path.contains(".JAR") || path.contains(".ZIP")) { return new Entry_Zip(path); } diff --git a/src/com/gabongao/jvm/classpath/Entry_Dir.java b/src/com/gabongao/jvm/classpath/Entry_Dir.java index 7c6945d..0c7d5c4 100644 --- a/src/com/gabongao/jvm/classpath/Entry_Dir.java +++ b/src/com/gabongao/jvm/classpath/Entry_Dir.java @@ -57,11 +57,6 @@ public class Entry_Dir extends Entry { while (-1 != (len=inputStream.read(buffer, 0, buf_size))) { bos.write(buffer, 0, len); } - for (byte b:bos.toByteArray() - ) { - System.out.printf("%x",b); - } - System.out.println(); return bos.toByteArray(); } catch (Exception e) { System.out.println("Class "+className+" not found"+" in "+absDir); diff --git a/src/com/gabongao/jvm/classpath/Entry_Wildcard.java b/src/com/gabongao/jvm/classpath/Entry_Wildcard.java index 0a23799..f3f2f0f 100644 --- a/src/com/gabongao/jvm/classpath/Entry_Wildcard.java +++ b/src/com/gabongao/jvm/classpath/Entry_Wildcard.java @@ -47,11 +47,11 @@ public class Entry_Wildcard extends Entry { Path dir = Paths.get(baseDir); try (DirectoryStream stream = Files.newDirectoryStream(dir)) { - for (Path e:stream - ) { + for (Path e : stream + ) { String fileName = e.getFileName().toString(); if ((!e.toFile().isDirectory()) && (fileName.contains(".jar") || fileName.contains(".JAR"))) { - entryList.add(new Entry_Zip(e.getParent()+"\\"+fileName)); + entryList.add(new Entry_Zip(e.getParent() + "\\" + fileName)); } } } catch (Exception e) { @@ -59,7 +59,10 @@ public class Entry_Wildcard extends Entry { } for (Entry entry : entryList ) { - entry.readClass(className); + byte[] bytes = entry.readClass(className); + if (bytes != null) { + return bytes; + } } return null; } diff --git a/src/com/gabongao/jvm/classpath/Entry_Zip.java b/src/com/gabongao/jvm/classpath/Entry_Zip.java index fa2b495..423d973 100644 --- a/src/com/gabongao/jvm/classpath/Entry_Zip.java +++ b/src/com/gabongao/jvm/classpath/Entry_Zip.java @@ -59,11 +59,6 @@ public class Entry_Zip extends Entry { while (-1 != (len = jarInput.read(buffer, 0, buf_size))) { bos.write(buffer, 0, len); } - for (byte b : bos.toByteArray() - ) { - System.out.printf("%x",b); - } - System.out.println(); return bos.toByteArray(); } entry = jarInput.getNextJarEntry(); diff --git a/src/test/com/gabongao/jvm/CmdTest.java b/src/test/com/gabongao/jvm/CmdTest.java index 37c4f11..0f57f27 100644 --- a/src/test/com/gabongao/jvm/CmdTest.java +++ b/src/test/com/gabongao/jvm/CmdTest.java @@ -82,7 +82,7 @@ public void testParseCmd() throws Exception { cmd.parseCmd(new String[]{"-classpath","classpath1","-version","MyApp","args1","args2"}); - assertEquals(true,"".equals(cmd.getXjre())); + assertEquals(true,"".equals(cmd.getJreOption())); assertEquals("classpath1",cmd.getCpOption()); assertEquals(false,cmd.isHelpFlag()); assertEquals(true,cmd.isVersionFlag()); @@ -94,7 +94,7 @@ public void testParseCmd() throws Exception { assertEquals("classpath1",cmd.getCpOption()); assertEquals(false,cmd.isHelpFlag()); assertEquals(true,cmd.isVersionFlag()); - assertEquals(true,"jreoption".equals(cmd.getXjre())); + assertEquals(true,"jreoption".equals(cmd.getJreOption())); assertEquals(true, Arrays.asList(new String[]{"args1", "args2","args3"}).equals(Arrays.asList(cmd.getArgs()))); assertEquals("MyApp",cmd.getClassName()); cmd.reset();