1 package org.compiere.tools; 2 3 import java.io.*; 4 import java.util.*; 5 import java.util.zip.*; 6 import java.util.jar.*; 7 8 46 public class ClassVersionLimiter 47 { 48 51 public static void main(String [] args) 52 { 53 ClassVersionLimiter classVersionLimiter = new ClassVersionLimiter("D:/j2sdk1.4b3p", 46, 0); 54 } 56 57 private long _maxAllowedVersion; 58 59 60 private PrintWriter m_out = null; 61 62 63 66 public ClassVersionLimiter(String rootDirectory, int mainVersion, int minorVersion) 67 { 68 _maxAllowedVersion = mainVersion * 65536 + minorVersion; 69 70 try 72 { 73 File logFile = new File(rootDirectory + File.separator + "patchJar.log"); 74 m_out = new PrintWriter(new FileOutputStream(logFile), true); System.out.println("Log=" + logFile.getAbsolutePath()); 76 } 77 catch (Exception e) 78 { 79 System.err.println("Cannot write log"); 80 e.printStackTrace(System.err); 81 System.exit(1); 82 } 83 84 File root = new File(rootDirectory); 86 search(root); 87 } 89 92 private void search(File dir) 93 { 94 dir.listFiles (new FileFilter() 95 { 96 public boolean accept(File pathname) 97 { 98 if (pathname.getName().endsWith(".jar")) 99 checkJar(pathname); 100 if (pathname.isDirectory()) 101 search(pathname); 102 return false; 103 } 104 }); 105 } 107 110 private void checkJar(File file) 111 { 112 byte[] header = new byte[8]; 113 long maxVersion = 0; 114 boolean foundClassFiles = false; 115 try 116 { 117 JarFile jarFile = new JarFile(file); 118 Enumeration entries = jarFile.entries(); 119 while (entries.hasMoreElements()) 120 { 121 JarEntry entry = (JarEntry) entries.nextElement(); 122 if (entry.getName().endsWith(".class")) 123 { 124 foundClassFiles = true; 125 InputStream stream = jarFile.getInputStream(entry); 126 stream.read(header); 127 int mainVersion = header[6] * 256 + header[7]; 128 int minorVersion = header[4] * 256 + header[5]; 129 long version = mainVersion * 65536 + minorVersion; 130 if (version > maxVersion) 131 maxVersion = version; 132 } 133 } 134 jarFile.close(); 135 if (foundClassFiles && maxVersion > _maxAllowedVersion) 136 { 137 patchJar(file); 138 } 139 } 140 catch (Exception e) 141 { 142 log ("checkJar", e); 143 } 144 } 146 149 private void patchJar(File file) 150 { 151 log ("Patching " + file, null); 152 try 153 { 154 final int MAX_ENTRY_SIZE = 1024 * 1024; byte[] classBytes = new byte[MAX_ENTRY_SIZE]; 156 File newFile = new File(file.getAbsolutePath() + ".NEW"); 157 158 CRC32 crc32 = new CRC32(); 159 JarFile oldJarFile = new JarFile(file); 160 Manifest manifest = oldJarFile.getManifest(); 161 FileOutputStream outputStream = new FileOutputStream(newFile); 162 JarOutputStream jarOutput = new JarOutputStream(outputStream, manifest); 163 Enumeration entries = oldJarFile.entries(); 164 165 while (entries.hasMoreElements()) 166 { 167 JarEntry oldEntry = (JarEntry) entries.nextElement(); 168 JarEntry newEntry = (JarEntry) oldEntry.clone(); 169 System.out.print("."); if (oldEntry.getName().equals("META-INF/MANIFEST.MF")) 171 continue; 172 173 InputStream in = oldJarFile.getInputStream(oldEntry); 175 int totalLen = 0; 176 int readLen = 0; 177 do 178 { 179 totalLen += readLen; 180 readLen = in.read(classBytes, totalLen, MAX_ENTRY_SIZE - totalLen); 181 } while(readLen > 0); 182 if (totalLen == MAX_ENTRY_SIZE) 183 { 184 log ("ERROR= patchJAR: MAX_ENTRY_SIZE too small - " + MAX_ENTRY_SIZE, null); 185 return; 186 } 187 188 if (totalLen > 0 && oldEntry.getName().endsWith(".class")) 189 { 190 int mainVersion = classBytes[6] * 256 + classBytes[7]; 191 int minorVersion = classBytes[4] * 256 + classBytes[5]; 192 long version = mainVersion * 65536 + minorVersion; 193 if (version > _maxAllowedVersion) 195 { 196 log (" - " + oldEntry.getName(), null); 197 mainVersion = (int) _maxAllowedVersion / 65536; 198 minorVersion = (int) _maxAllowedVersion % 65536; 199 classBytes[4] = (byte) (minorVersion / 256); 200 classBytes[5] = (byte) (minorVersion % 256); 201 classBytes[6] = (byte) (mainVersion / 256); 202 classBytes[7] = (byte) (mainVersion % 256); 203 204 crc32.reset(); 205 crc32.update(classBytes, 0, totalLen); 206 newEntry.setCrc(crc32.getValue()); 207 newEntry.setCompressedSize(-1); 209 } 210 } 211 jarOutput.putNextEntry(newEntry); 212 if (totalLen > 0) 213 jarOutput.write(classBytes, 0, totalLen); 214 jarOutput.closeEntry(); 215 } 216 jarOutput.close(); 217 outputStream.close(); 218 oldJarFile.close(); 219 log ("", null); 221 222 File bakFile = new File(file.getAbsolutePath() + ".BAK"); 224 if (!file.renameTo(bakFile)) 225 { 226 log ("ERROR= Cannot rename " + file + " to " + bakFile + ". EXITING.", null); 227 System.exit(99); 228 } 229 if(!newFile.renameTo(file)) 230 { 231 log ("ERROR= Cannot rename " + newFile + " to " + file + ". EXITING.", null); 232 System.exit(99); 233 } 234 } 235 catch (Exception e) 236 { 237 log ("patchJar", e); 238 } 239 } 241 244 private void log (String message, Exception e) 245 { 246 if (e == null) 247 { 248 System.out.println(message); 249 m_out.println(message); 250 } 251 else 252 { 253 System.err.print("ERROR= "); 254 System.err.println(message); 255 e.printStackTrace(System.err); 256 m_out.print("ERROR= "); 258 m_out.println(message); 259 e.printStackTrace(m_out); 260 } 261 } 263 } 265 | Popular Tags |