KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > retrotranslator > transformer > JITRetrotranslator


1 /***
2  * Retrotranslator: a Java bytecode transformer that translates Java classes
3  * compiled with JDK 5.0 into classes that can be run on JVM 1.4.
4  *
5  * Copyright (c) 2005 - 2007 Taras Puchko
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the copyright holders nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30  * THE POSSIBILITY OF SUCH DAMAGE.
31  */

32 package net.sf.retrotranslator.transformer;
33
34 import java.io.File JavaDoc;
35 import net.sf.retrotranslator.runtime.impl.*;
36
37 /**
38  * @author Taras Puchko
39  */

40 public class JITRetrotranslator {
41
42     private boolean advanced;
43     private String JavaDoc backport;
44
45     public JITRetrotranslator() {
46     }
47
48     public void setAdvanced(boolean advanced) {
49         this.advanced = advanced;
50     }
51
52     public void setBackport(String JavaDoc backport) {
53         this.backport = backport;
54     }
55
56     public boolean run() {
57         if (isJava5Supported()) return true;
58         ReplacementLocatorFactory factory = new ReplacementLocatorFactory(
59                 ClassVersion.VERSION_14, advanced, false, Backport.asList(backport));
60         ClassTransformer transformer = new ClassTransformer(true, false, false, null, null, factory);
61         ClassDescriptor.setBytecodeTransformer(transformer);
62         SunJITRetrotranslator.install(transformer);
63         if (isJava5Supported()) return true;
64         JRockitJITRetrotranslator.install(transformer);
65         return isJava5Supported();
66     }
67
68     private static boolean isJava5Supported() {
69         class ClassFactory extends ClassLoader JavaDoc {
70             public Class JavaDoc defineClass(String JavaDoc name, byte[] bytes) {
71                 return defineClass(name, bytes, 0, bytes.length);
72             }
73         }
74         byte[] bytes = RuntimeTools.getBytecode(JITRetrotranslator.class);
75         System.arraycopy(new byte[]{0, 0, 0, 49}, 0, bytes, 4, 4);
76         try {
77             new ClassFactory().defineClass(JITRetrotranslator.class.getName(), bytes);
78             return true;
79         } catch (ClassFormatError JavaDoc e) {
80             return false;
81         }
82     }
83
84     public static void main(String JavaDoc[] args) throws Exception JavaDoc {
85         JITRetrotranslator jit = new JITRetrotranslator();
86         boolean jar = false;
87         int i;
88         for (i = 0; i < args.length; i++) {
89             String JavaDoc option = args[i];
90             if (option.equals("-advanced")) {
91                 jit.setAdvanced(true);
92             } else if (option.equals("-backport") && i + 1 < args.length) {
93                 jit.setBackport(args[++i]);
94             } else if (option.equals("-jar")) {
95                 jar = true;
96                 i++;
97                 break;
98             } else {
99                 break;
100             }
101         }
102         if (i == args.length) {
103             printUsageAndExit();
104         }
105         if (!jit.run()) {
106             System.out.println("Cannot install JIT Retrotranslator.");
107         }
108         if (jar) {
109             File JavaDoc file = new File JavaDoc(args[i]);
110             if (!file.isFile()) printErrorAndExit("Unable to access jarfile " + file);
111             JarClassLoader classLoader = new JarClassLoader(file, getClassLoader());
112             String JavaDoc mainClass = classLoader.getMainClass();
113             if (mainClass == null) printErrorAndExit("Failed to load Main-Class manifest attribute from " + file);
114             Thread.currentThread().setContextClassLoader(classLoader);
115             execute(classLoader, mainClass, remove(args, i + 1));
116         } else {
117             execute(getClassLoader(), args[i], remove(args, i + 1));
118         }
119     }
120
121     private static ClassLoader JavaDoc getClassLoader() {
122         ClassLoader JavaDoc classLoader = JITRetrotranslator.class.getClassLoader();
123         return classLoader != null ? classLoader : ClassLoader.getSystemClassLoader();
124     }
125
126     private static String JavaDoc[] remove(String JavaDoc[] original, int count) {
127         String JavaDoc[] result = new String JavaDoc[original.length - count];
128         System.arraycopy(original, original.length - result.length, result, 0, result.length);
129         return result;
130     }
131
132     private static void execute(ClassLoader JavaDoc classLoader, String JavaDoc mainClass, String JavaDoc[] args) throws Exception JavaDoc {
133         try {
134             classLoader.loadClass(mainClass).getMethod("main", String JavaDoc[].class).invoke(null, new Object JavaDoc[]{args});
135         } catch (NoSuchMethodException JavaDoc e) {
136             printErrorAndExit("Could not find the method \"main\" in: " + mainClass);
137         } catch (ClassNotFoundException JavaDoc e) {
138             printErrorAndExit("Could not find the main class: " + mainClass);
139         }
140     }
141
142     private static void printUsageAndExit() {
143         String JavaDoc version = JITRetrotranslator.class.getPackage().getImplementationVersion();
144         String JavaDoc suffix = (version == null) ? "" : "-" + version;
145         StringBuilder JavaDoc builder = new StringBuilder JavaDoc("Usage: java -cp retrotranslator-transformer").append(suffix);
146         builder.append(".jar").append(File.pathSeparator);
147         builder.append("<classpath> net.sf.retrotranslator.transformer.JITRetrotranslator" +
148                 " [-advanced] [-backport <packages>] <class> [<args...>]\n");
149         builder.append(" or java -cp retrotranslator-transformer").append(suffix);
150         builder.append(".jar net.sf.retrotranslator.transformer.JITRetrotranslator" +
151                 " [-advanced] [-backport <packages>] -jar <jarfile> [<args...>]");
152         System.out.println(builder);
153         System.exit(1);
154     }
155
156     private static void printErrorAndExit(String JavaDoc msg) {
157         System.out.println(msg);
158         System.exit(1);
159     }
160 }
161
Popular Tags