Fri, 14 Mar 2008 16:09:30 -0700
6638501: Regression with Javac in JDK6 U4 b03?
Summary: replace some String paths with File paths in Paths.java
Reviewed-by: ksrini
1.1 --- a/src/share/classes/com/sun/tools/javac/util/Paths.java Thu Mar 13 13:42:38 2008 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/util/Paths.java Fri Mar 14 16:09:30 2008 -0700 1.3 @@ -38,13 +38,8 @@ 1.4 import java.util.LinkedHashSet; 1.5 import java.util.Iterator; 1.6 import java.util.StringTokenizer; 1.7 -import java.util.zip.ZipException; 1.8 import java.util.zip.ZipFile; 1.9 import com.sun.tools.javac.code.Lint; 1.10 -import com.sun.tools.javac.util.Context; 1.11 -import com.sun.tools.javac.util.Log; 1.12 -import com.sun.tools.javac.util.Options; 1.13 -import com.sun.tools.javac.util.Position; 1.14 import java.util.ArrayList; 1.15 import java.util.concurrent.ConcurrentHashMap; 1.16 import java.util.concurrent.locks.Lock; 1.17 @@ -70,7 +65,10 @@ 1.18 protected static final Context.Key<Paths> pathsKey = 1.19 new Context.Key<Paths>(); 1.20 1.21 - /** Get the Paths instance for this context. */ 1.22 + /** Get the Paths instance for this context. 1.23 + * @param context the context 1.24 + * @return the Paths instance for this context 1.25 + */ 1.26 public static Paths instance(Context context) { 1.27 Paths instance = context.get(pathsKey); 1.28 if (instance == null) 1.29 @@ -89,7 +87,7 @@ 1.30 1.31 private static boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this. 1.32 private static Map<File, PathEntry> pathExistanceCache = new ConcurrentHashMap<File, PathEntry>(); 1.33 - private static Map<File, java.util.List<String>> manifestEntries = new ConcurrentHashMap<File, java.util.List<String>>(); 1.34 + private static Map<File, java.util.List<File>> manifestEntries = new ConcurrentHashMap<File, java.util.List<File>>(); 1.35 private static Map<File, Boolean> isDirectory = new ConcurrentHashMap<File, Boolean>(); 1.36 private static Lock lock = new ReentrantLock(); 1.37 1.38 @@ -369,13 +367,13 @@ 1.39 // filenames, but if we do, we should redo all path-related code. 1.40 private void addJarClassPath(File jarFile, boolean warn) { 1.41 try { 1.42 - java.util.List<String> manifestsList = manifestEntries.get(jarFile); 1.43 + java.util.List<File> manifestsList = manifestEntries.get(jarFile); 1.44 if (!NON_BATCH_MODE) { 1.45 lock.lock(); 1.46 try { 1.47 if (manifestsList != null) { 1.48 - for (String entr : manifestsList) { 1.49 - addFile(new File(entr), warn); 1.50 + for (File entr : manifestsList) { 1.51 + addFile(entr, warn); 1.52 } 1.53 return; 1.54 } 1.55 @@ -386,7 +384,7 @@ 1.56 } 1.57 1.58 if (!NON_BATCH_MODE) { 1.59 - manifestsList = new ArrayList<String>(); 1.60 + manifestsList = new ArrayList<File>(); 1.61 manifestEntries.put(jarFile, manifestsList); 1.62 } 1.63 1.64 @@ -412,7 +410,7 @@ 1.65 if (!NON_BATCH_MODE) { 1.66 lock.lock(); 1.67 try { 1.68 - manifestsList.add(elt); 1.69 + manifestsList.add(f); 1.70 } 1.71 finally { 1.72 lock.unlock();
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/tools/javac/Paths/6638501/HelloLib/test/HelloImpl.java Fri Mar 14 16:09:30 2008 -0700 2.3 @@ -0,0 +1,32 @@ 2.4 +/* 2.5 + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 2.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 2.24 + * have any questions. 2.25 + */ 2.26 + 2.27 +package test; 2.28 + 2.29 +public class HelloImpl { 2.30 + 2.31 + public void Hello() { 2.32 + java.lang.System.out.println("Hello"); 2.33 + } 2.34 + 2.35 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/tools/javac/Paths/6638501/JarFromManifestFailure.java Fri Mar 14 16:09:30 2008 -0700 3.3 @@ -0,0 +1,169 @@ 3.4 +/* 3.5 + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. 3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.7 + * 3.8 + * This code is free software; you can redistribute it and/or modify it 3.9 + * under the terms of the GNU General Public License version 2 only, as 3.10 + * published by the Free Software Foundation. 3.11 + * 3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.15 + * version 2 for more details (a copy is included in the LICENSE file that 3.16 + * accompanied this code). 3.17 + * 3.18 + * You should have received a copy of the GNU General Public License version 3.19 + * 2 along with this work; if not, write to the Free Software Foundation, 3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.21 + * 3.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 3.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 3.24 + * have any questions. 3.25 + */ 3.26 + 3.27 +/* 3.28 + * @test 3.29 + * @bug 6638501 3.30 + * @summary REGRESSION: Java Compiler cannot find jar files referenced by other 3.31 + * @run main JarFromManifestFailure 3.32 + */ 3.33 + 3.34 +import java.io.*; 3.35 +import java.nio.*; 3.36 +import java.util.*; 3.37 +import java.util.jar.*; 3.38 +import javax.tools.*; 3.39 +import javax.tools.StandardJavaFileManager.*; 3.40 + 3.41 +public class JarFromManifestFailure { 3.42 + static File testSrc = new File(System.getProperty("test.src", ".")); 3.43 + static File testClasses = new File(System.getProperty("test.classes", ".")); 3.44 + 3.45 + public static void main(String... args) throws Exception { 3.46 + compile(testClasses, null, new File(testSrc, "HelloLib/test/HelloImpl.java"), new File(testSrc, "WsCompileExample.java")); 3.47 + File libFile = new File(testClasses, "lib"); 3.48 + libFile.mkdir(); 3.49 + jar(new File(libFile, "HelloLib.jar"), new ArrayList(), testClasses, new File("test")); 3.50 + 3.51 + ArrayList arList = new ArrayList(); 3.52 + arList.add(new File("HelloLib.jar")); 3.53 + jar(new File(libFile, "JarPointer.jar"), arList, testClasses); 3.54 + 3.55 + String[] args1 = { 3.56 + "-d", ".", 3.57 + "-cp", new File(libFile, "JarPointer.jar").getPath().replace('\\', '/'), 3.58 + new File(testSrc, "test/SayHello.java").getPath().replace('\\', '/') 3.59 + }; 3.60 + System.err.println("First compile!!!"); 3.61 + if (com.sun.tools.javac.Main.compile(args1) != 0) { 3.62 + throw new AssertionError("Failure in first compile!"); 3.63 + } 3.64 + 3.65 + System.err.println("Second compile!!!"); 3.66 + 3.67 + args1 = new String[] { 3.68 + "-d", ".", 3.69 + "-cp", new File(libFile, "JarPointer.jar").getPath().replace('\\', '/'), 3.70 + new File(testSrc, "test1/SayHelloToo.java").getPath().replace('\\', '/') 3.71 + }; 3.72 + if (com.sun.tools.javac.Main.compile(args1) != 0) { 3.73 + throw new AssertionError("Failure in second compile!"); 3.74 + } 3.75 + } 3.76 + 3.77 + static void compile(File classOutDir, Iterable<File> classPath, File... files) { 3.78 + System.err.println("compile..."); 3.79 + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 3.80 + StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); 3.81 + Iterable<? extends JavaFileObject> fileObjects = 3.82 + fm.getJavaFileObjectsFromFiles(Arrays.asList(files)); 3.83 + 3.84 + List<String> options = new ArrayList<String>(); 3.85 + if (classOutDir != null) { 3.86 + options.add("-d"); 3.87 + options.add(classOutDir.getPath()); 3.88 + } 3.89 + if (classPath != null) { 3.90 + options.add("-classpath"); 3.91 + options.add(join(classPath, File.pathSeparator)); 3.92 + } 3.93 + options.add("-verbose"); 3.94 + 3.95 + JavaCompiler.CompilationTask task = 3.96 + compiler.getTask(null, fm, null, options, null, fileObjects); 3.97 + if (!task.call()) 3.98 + throw new AssertionError("compilation failed"); 3.99 + } 3.100 + 3.101 + static void jar(File jar, Iterable<File> classPath, File base, File... files) 3.102 + throws IOException { 3.103 + System.err.println("jar..."); 3.104 + Manifest m = new Manifest(); 3.105 + if (classPath != null) { 3.106 + Attributes mainAttrs = m.getMainAttributes(); 3.107 + mainAttrs.put(Attributes.Name.MANIFEST_VERSION, "1.0"); 3.108 + mainAttrs.put(Attributes.Name.CLASS_PATH, join(classPath, " ")); 3.109 + } 3.110 + OutputStream out = new BufferedOutputStream(new FileOutputStream(jar)); 3.111 + JarOutputStream j = new JarOutputStream(out, m); 3.112 + add(j, base, files); 3.113 + j.close(); 3.114 + } 3.115 + 3.116 + static void add(JarOutputStream j, File base, File... files) throws IOException { 3.117 + if (files == null) 3.118 + return; 3.119 + 3.120 + for (File f: files) 3.121 + add(j, base, f); 3.122 + } 3.123 + 3.124 + static void add(JarOutputStream j, File base, File file) throws IOException { 3.125 + File f = new File(base, file.getPath()); 3.126 + if (f.isDirectory()) { 3.127 + JarEntry e = new JarEntry(new String(file.getPath() + File.separator).replace('\\', '/')); 3.128 + e.setSize(file.length()); 3.129 + j.putNextEntry(e); 3.130 + String[] children = f.list(); 3.131 + if (children != null) { 3.132 + for (String c: children) { 3.133 + add(j, base, new File(file, c)); 3.134 + } 3.135 + } 3.136 + } else { 3.137 + JarEntry e = new JarEntry(file.getPath().replace('\\', '/')); 3.138 + e.setSize(f.length()); 3.139 + j.putNextEntry(e); 3.140 + j.write(read(f)); 3.141 + j.closeEntry(); 3.142 + } 3.143 + 3.144 + } 3.145 + 3.146 + static byte[] read(File f) throws IOException { 3.147 + byte[] buf = new byte[(int) f.length()]; 3.148 + BufferedInputStream in = new BufferedInputStream(new FileInputStream(f)); 3.149 + int offset = 0; 3.150 + while (offset < buf.length) { 3.151 + int n = in.read(buf, offset, buf.length - offset); 3.152 + if (n < 0) 3.153 + throw new EOFException(); 3.154 + offset += n; 3.155 + } 3.156 + return buf; 3.157 + } 3.158 + 3.159 + static <T> Iterable<T> iterable(T single) { 3.160 + return Collections.singleton(single); 3.161 + } 3.162 + 3.163 + static <T> String join(Iterable<T> iter, String sep) { 3.164 + StringBuilder p = new StringBuilder(); 3.165 + for (T t: iter) { 3.166 + if (p.length() > 0) 3.167 + p.append(' '); 3.168 + p.append(t); 3.169 + } 3.170 + return p.toString(); 3.171 + } 3.172 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/tools/javac/Paths/6638501/WsCompileExample.java Fri Mar 14 16:09:30 2008 -0700 4.3 @@ -0,0 +1,189 @@ 4.4 +/* 4.5 + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. 4.11 + * 4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.15 + * version 2 for more details (a copy is included in the LICENSE file that 4.16 + * accompanied this code). 4.17 + * 4.18 + * You should have received a copy of the GNU General Public License version 4.19 + * 2 along with this work; if not, write to the Free Software Foundation, 4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.21 + * 4.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 4.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 4.24 + * have any questions. 4.25 + */ 4.26 + 4.27 +import java.util.List; 4.28 +import java.util.ArrayList; 4.29 +import java.io.File; 4.30 +//for CompilerHelper 4.31 +import java.io.OutputStream; 4.32 +import java.io.PrintWriter; 4.33 +import java.lang.reflect.Method; 4.34 +import java.lang.reflect.InvocationTargetException; 4.35 + 4.36 + 4.37 + 4.38 +public class WsCompileExample { 4.39 + File destDir; 4.40 + File srcDir; 4.41 + protected boolean compilerDebug = false; 4.42 + protected boolean compilerOptimize = false; 4.43 + protected String userClasspath = null; 4.44 + 4.45 + public static void main(String[] args) { 4.46 + new WsCompileExample().do_main(args); 4.47 + } 4.48 + 4.49 + public void do_main(String[] args) { 4.50 + if(!args[0].equals("-s")) { 4.51 + throw new RuntimeException("specify -s for src"); 4.52 + } 4.53 + 4.54 + //run it once 4.55 + srcDir = new File(args[1]); 4.56 + if(!args[2].equals("-d")) { 4.57 + throw new RuntimeException("specify -d for dest"); 4.58 + } 4.59 + destDir = new File(args[3]); 4.60 + if(!destDir.exists()) 4.61 + destDir.mkdirs(); 4.62 + System.out.println("----test compile 1-----"); 4.63 + compileGeneratedClasses(); 4.64 + 4.65 + //run it twice 4.66 + srcDir = new File(args[1]+"1"); 4.67 + destDir = new File(args[3]+"1"); 4.68 + if(!destDir.exists()) 4.69 + destDir.mkdirs(); 4.70 + System.out.println("----test compile 2-----"); 4.71 + compileGeneratedClasses(); 4.72 + 4.73 + } 4.74 + protected void compileGeneratedClasses() { 4.75 + List sourceFiles = new ArrayList(); 4.76 + 4.77 + for (File f: srcDir.listFiles()) { 4.78 + if (f.getName().endsWith(".java")) { 4.79 + sourceFiles.add(f.getAbsolutePath()); 4.80 + } 4.81 + } 4.82 + 4.83 + if (sourceFiles.size() > 0) { 4.84 + String classDir = destDir.getAbsolutePath(); 4.85 + String classpathString = createClasspathString(); 4.86 + System.out.println("classpathString: " + classpathString); 4.87 + 4.88 + String[] args = new String[4 + (compilerDebug == true ? 1 : 0) + 4.89 + (compilerOptimize == true ? 1 : 0) + 4.90 + sourceFiles.size()]; 4.91 + args[0] = "-d"; 4.92 + args[1] = classDir; 4.93 + args[2] = "-classpath"; 4.94 + args[3] = classpathString; 4.95 +// args[4]="-DnonBatchMode"; 4.96 + int baseIndex = 4; 4.97 + if (compilerDebug) { 4.98 + args[baseIndex++] = "-g"; 4.99 + } 4.100 + if (compilerOptimize) { 4.101 + args[baseIndex++] = "-O"; 4.102 + } 4.103 + for (int i = 0; i < sourceFiles.size(); ++i) { 4.104 + args[baseIndex + i] = (String)sourceFiles.get(i); 4.105 + } 4.106 + 4.107 + // ByteArrayOutputStream javacOutput = new ByteArrayOutputStream(); 4.108 + JavaCompilerHelper compilerHelper = new JavaCompilerHelper(System.out); 4.109 + boolean result = compilerHelper.compile(args); 4.110 + if (!result) { 4.111 + System.out.println("wscompile.compilation Failed"); 4.112 + } 4.113 + } 4.114 + } 4.115 + 4.116 + protected String createClasspathString() { 4.117 + if (userClasspath == null) { 4.118 + userClasspath = ""; 4.119 + } 4.120 + String jcp = userClasspath + File.pathSeparator + System.getProperty("java.class.path"); 4.121 + return jcp; 4.122 + } 4.123 +} 4.124 +/////////////////////////////////////////////////////////////////// 4.125 +class JavaCompilerHelper { 4.126 + public JavaCompilerHelper(OutputStream out) { 4.127 + this.out = out; 4.128 + } 4.129 + 4.130 + public boolean compile(String[] args) { 4.131 + return internalCompile(args); 4.132 + } 4.133 + 4.134 + protected boolean internalCompile(String[] args) { 4.135 + 4.136 + System.out.println("Args: "); 4.137 + for(String arg : args){ 4.138 + System.out.print(arg+" "); 4.139 + } 4.140 + System.out.println(); 4.141 + ClassLoader cl = Thread.currentThread().getContextClassLoader(); 4.142 + Class comSunToolsJavacMainClass = null; 4.143 + try { 4.144 + /* try to use the new compiler */ 4.145 + comSunToolsJavacMainClass = 4.146 + cl.loadClass("com.sun.tools.javac.Main"); 4.147 + try { 4.148 + Method compileMethod = 4.149 + comSunToolsJavacMainClass.getMethod( 4.150 + "compile", 4.151 + compile141MethodSignature); 4.152 + try { 4.153 + Object result = 4.154 + compileMethod.invoke( 4.155 + null, 4.156 + new Object[] { args, new PrintWriter(out)}); 4.157 + if (!(result instanceof Integer)) { 4.158 + return false; 4.159 + } 4.160 + return ((Integer) result).intValue() == 0; 4.161 + } catch (IllegalAccessException e3) { 4.162 + return false; 4.163 + } catch (IllegalArgumentException e3) { 4.164 + return false; 4.165 + } catch (InvocationTargetException e3) { 4.166 + return false; 4.167 + } 4.168 + } catch (NoSuchMethodException e2) { 4.169 + System.out.println("ERROR: Compile failed with error:" + e2.toString() ); 4.170 + } 4.171 + } catch (ClassNotFoundException e) { 4.172 + e.printStackTrace(); 4.173 + return false; 4.174 + } catch (SecurityException e) { 4.175 + return false; 4.176 + } 4.177 + return true; 4.178 + } 4.179 + 4.180 + protected String getGenericErrorMessage() {return "javacompiler.error"; } 4.181 + protected void run() { } 4.182 + protected boolean parseArguments(String[] args) {return false;} 4.183 + protected OutputStream out; 4.184 + 4.185 + protected static final Class[] compile141MethodSignature; 4.186 + static 4.187 + { 4.188 + compile141MethodSignature = new Class[2]; 4.189 + compile141MethodSignature[0] = (new String[0]).getClass(); 4.190 + compile141MethodSignature[1] = PrintWriter.class; 4.191 + } 4.192 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/tools/javac/Paths/6638501/test/SayHello.java Fri Mar 14 16:09:30 2008 -0700 5.3 @@ -0,0 +1,31 @@ 5.4 +/* 5.5 + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. 5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.7 + * 5.8 + * This code is free software; you can redistribute it and/or modify it 5.9 + * under the terms of the GNU General Public License version 2 only, as 5.10 + * published by the Free Software Foundation. 5.11 + * 5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 5.15 + * version 2 for more details (a copy is included in the LICENSE file that 5.16 + * accompanied this code). 5.17 + * 5.18 + * You should have received a copy of the GNU General Public License version 5.19 + * 2 along with this work; if not, write to the Free Software Foundation, 5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 5.21 + * 5.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 5.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 5.24 + * have any questions. 5.25 + */ 5.26 + 5.27 +import test.HelloImpl; 5.28 + 5.29 +public class SayHello extends HelloImpl { 5.30 + public static void main(String... args) { 5.31 + new SayHello().Hello(); 5.32 +} 5.33 + 5.34 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/tools/javac/Paths/6638501/test1/SayHelloToo.java Fri Mar 14 16:09:30 2008 -0700 6.3 @@ -0,0 +1,31 @@ 6.4 +/* 6.5 + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. 6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 + * 6.8 + * This code is free software; you can redistribute it and/or modify it 6.9 + * under the terms of the GNU General Public License version 2 only, as 6.10 + * published by the Free Software Foundation. 6.11 + * 6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.15 + * version 2 for more details (a copy is included in the LICENSE file that 6.16 + * accompanied this code). 6.17 + * 6.18 + * You should have received a copy of the GNU General Public License version 6.19 + * 2 along with this work; if not, write to the Free Software Foundation, 6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.21 + * 6.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 6.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 6.24 + * have any questions. 6.25 + */ 6.26 + 6.27 +import test.HelloImpl; 6.28 + 6.29 +public class SayHelloToo extends HelloImpl { 6.30 + public static void main(String... args) { 6.31 + new SayHelloToo().Hello(); 6.32 +} 6.33 + 6.34 +}