ch02 finish

This commit is contained in:
Imgaojp 2017-02-17 18:30:08 +08:00
parent ee30abbf2d
commit ce66f8c134
8 changed files with 130 additions and 29 deletions

View File

@ -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) {

View File

@ -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);
}
}
}

View File

@ -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();
}
}

View File

@ -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);
}

View File

@ -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);

View File

@ -47,11 +47,11 @@ public class Entry_Wildcard extends Entry {
Path dir = Paths.get(baseDir);
try (DirectoryStream<Path> 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;
}

View File

@ -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();

View File

@ -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();