1 7 8 package javax.management.loading; 9 10 11 import java.io.Externalizable ; 13 import java.io.File ; 14 import java.io.FileOutputStream ; 15 import java.io.InputStream ; 16 import java.io.IOException ; 17 import java.io.ObjectInput ; 18 import java.io.ObjectInputStream ; 19 import java.io.ObjectOutput ; 20 import java.lang.reflect.Constructor ; 21 import java.net.MalformedURLException ; 22 import java.net.URL ; 23 import java.net.URLClassLoader ; 24 import java.net.URLStreamHandlerFactory ; 25 import java.security.AccessController ; 26 import java.security.PrivilegedAction ; 27 import java.util.Arrays ; 28 import java.util.Enumeration ; 29 import java.util.HashSet ; 30 import java.util.Hashtable ; 31 import java.util.Iterator ; 32 import java.util.Map ; 33 import java.util.Set ; 34 import java.util.StringTokenizer ; 35 import java.util.Vector ; 36 37 import javax.management.ServiceNotFoundException ; 38 import javax.management.ObjectInstance ; 39 import javax.management.ObjectName ; 40 import javax.management.MBeanServer ; 41 import javax.management.ReflectionException ; 42 import javax.management.InstanceAlreadyExistsException ; 43 import javax.management.MBeanRegistrationException ; 44 import javax.management.MBeanException ; 45 import javax.management.NotCompliantMBeanException ; 46 import javax.management.InstanceNotFoundException ; 47 import javax.management.MBeanRegistration ; 48 import javax.management.MBeanServerFactory ; 49 import javax.management.loading.ClassLoaderRepository ; 50 51 import com.sun.jmx.mbeanserver.GetPropertyAction; 52 53 import com.sun.jmx.defaults.ServiceName; 54 import com.sun.jmx.defaults.JmxProperties; 55 56 import com.sun.jmx.trace.Trace; 57 58 59 155 public class MLet extends java.net.URLClassLoader 156 implements MLetMBean , MBeanRegistration , Externalizable { 157 158 private static final long serialVersionUID = 3636148327800330130L; 159 160 165 166 170 private MBeanServer server = null; 171 172 173 178 private Vector mletList = new Vector (); 179 180 181 184 private String libraryDirectory; 185 186 187 191 private ObjectName mletObjectName = null; 192 193 197 private URL [] myUrls = null; 198 199 202 private static final String dbgTag = "MLet"; 203 204 208 private transient ClassLoaderRepository currentClr; 209 210 214 private transient boolean delegateToCLR; 215 216 219 private Hashtable primitiveClasses = new Hashtable (8) ; 220 { 221 primitiveClasses.put(Boolean.TYPE.toString(), Boolean .class); 222 primitiveClasses.put(Character.TYPE.toString(), Character .class); 223 primitiveClasses.put(Byte.TYPE.toString(), Byte .class); 224 primitiveClasses.put(Short.TYPE.toString(), Short .class); 225 primitiveClasses.put(Integer.TYPE.toString(), Integer .class); 226 primitiveClasses.put(Long.TYPE.toString(), Long .class); 227 primitiveClasses.put(Float.TYPE.toString(), Float .class); 228 primitiveClasses.put(Double.TYPE.toString(), Double .class); 229 230 } 231 232 233 238 239 247 248 251 public MLet() { 252 this(new URL [0]); 253 } 254 255 264 public MLet(URL [] urls) { 265 this(urls, true); 266 } 267 268 279 public MLet(URL [] urls, ClassLoader parent) { 280 this(urls, parent, true); 281 } 282 283 295 public MLet(URL [] urls, 296 ClassLoader parent, 297 URLStreamHandlerFactory factory) { 298 this(urls, parent, factory, true); 299 } 300 301 314 public MLet(URL [] urls, boolean delegateToCLR) { 315 super(urls); 316 init(delegateToCLR); 317 } 318 319 334 public MLet(URL [] urls, ClassLoader parent, boolean delegateToCLR) { 335 super(urls, parent); 336 init(delegateToCLR); 337 } 338 339 355 public MLet(URL [] urls, 356 ClassLoader parent, 357 URLStreamHandlerFactory factory, 358 boolean delegateToCLR) { 359 super(urls, parent, factory); 360 init(delegateToCLR); 361 } 362 363 private void init(boolean delegateToCLR) { 364 this.delegateToCLR = delegateToCLR; 365 366 try { 367 libraryDirectory = System.getProperty(JmxProperties.MLET_LIB_DIR); 368 if (libraryDirectory == null) 369 libraryDirectory = getTmpDir(); 370 } catch (SecurityException e) { 371 } 376 } 377 378 379 384 385 386 390 public void addURL(URL url) { 391 if (!Arrays.asList(getURLs()).contains(url)) 392 super.addURL(url); 393 } 394 395 400 public void addURL(String url) throws ServiceNotFoundException { 401 try { 402 URL ur = new URL (url); 403 if (!Arrays.asList(getURLs()).contains(ur)) 404 super.addURL(ur); 405 } catch (MalformedURLException e) { 406 debug("addURL", url + ": Malformed URL. " + e); 407 throw new 408 ServiceNotFoundException ("The specified URL is malformed"); 409 } 410 } 411 412 416 public URL [] getURLs() { 417 return super.getURLs(); 418 } 419 420 438 public Set getMBeansFromURL(URL url) throws ServiceNotFoundException { 439 if (url == null) { 440 throw new ServiceNotFoundException ("The specified URL is null"); 441 } 442 return getMBeansFromURL(url.toString()); 443 } 444 445 463 public Set getMBeansFromURL(String url) throws ServiceNotFoundException { 464 465 String mth = "getMBeansFromURL"; 466 467 if (server == null) { 468 throw new IllegalStateException ("This MLet MBean is not registered with an MBeanServer."); 469 } 470 if (url == null) { 472 if (isTraceOn()) { 473 trace(mth, "URL is null"); 474 } 475 throw new ServiceNotFoundException ("The specified URL is null"); 476 } else { 477 url = url.replace(File.separatorChar,'/'); 478 } 479 if (isTraceOn()) { 480 trace(mth, "<URL = " + url + ">"); 481 } 482 483 try { 485 MLetParser parser = new MLetParser (); 486 mletList = parser.parseURL(url); 487 } catch (Exception e) { 488 final String msg = 489 "Problems while parsing URL [" + url + 490 "], got exception [" + e.toString() + "]"; 491 if (isTraceOn()) { 492 trace(mth, msg); 493 } 494 ServiceNotFoundException snfe = new ServiceNotFoundException (msg); 495 502 try { 503 java.lang.reflect.Method initCause = 504 Throwable .class.getMethod("initCause", 505 new Class [] {Throwable .class}); 506 initCause.invoke(snfe, new Object [] {e}); 507 } catch (Exception x) { 508 } 510 throw snfe; 511 } 512 513 if (mletList.size() == 0) { 515 if (isTraceOn()) { 516 trace(mth, "File " + url + " not found or MLET tag not defined in file"); 517 } 518 throw new ServiceNotFoundException ("File " + url + " not found or MLET tag not defined in file"); 519 } 520 521 HashSet mbeans = new HashSet (); 523 for(Enumeration e = mletList.elements(); e.hasMoreElements(); ) { 524 MLetContent elmt = (MLetContent ) e.nextElement(); 526 String code = elmt.getCode(); 528 if (code != null) { 529 if (code.endsWith(".class")) { 530 code = code.substring(0, code.length() - 6); 531 } 532 } 533 String name = elmt.getName(); 534 URL codebase = elmt.getCodeBase(); 535 String version = elmt.getVersion(); 536 String serName = elmt.getSerializedObject(); 537 String jarFiles = elmt.getJarFiles(); 538 URL documentBase = elmt.getDocumentBase(); 539 Map attributes = elmt.getAttributes(); 540 541 if (isTraceOn()) { 543 trace(mth, "MLET TAG = " + attributes.toString()); 544 trace(mth, "CODEBASE = " + codebase); 545 trace(mth, "ARCHIVE = " + jarFiles); 546 trace(mth, "CODE = " + code); 547 trace(mth, "OBJECT = " + serName); 548 trace(mth, "NAME = " + name); 549 trace(mth, "VERSION = " + version); 550 trace(mth, "DOCUMENT URL = " + documentBase); 551 } 552 553 StringTokenizer st = new StringTokenizer (jarFiles, ",", false); 555 while (st.hasMoreTokens()) { 556 String tok = st.nextToken().trim(); 557 if (isTraceOn()) { 558 trace(mth, "Load archive for codebase <" + codebase + ">, file <" + tok + ">"); 559 } 560 try { 567 codebase = check(version, codebase, tok, elmt); 568 } catch (Exception ex) { 569 if (isDebugOn()) { 570 debug(mth, "check returned exception: " + ex); 571 } 572 mbeans.add(ex); 573 continue; 574 } 575 576 try { 578 if (!Arrays.asList(getURLs()).contains(new URL (codebase.toString() + tok))) { 579 addURL(codebase + tok); 580 } 581 } catch (MalformedURLException me) { 582 } 584 585 } 586 Object o = null; 590 ObjectInstance objInst = null; 591 592 if (code != null && serName != null) { 593 if (isTraceOn()) { 594 trace(mth, "CODE and OBJECT parameters cannot be specified at the same time in tag MLET."); 595 } 596 mbeans.add(new Error ("CODE and OBJECT parameters cannot be specified at the same time in tag MLET")); 597 continue; 598 } 599 if (code == null && serName == null) { 600 if (isTraceOn()) { 601 trace(mth, "Either CODE or OBJECT parameter must be specified in tag MLET."); 602 } 603 mbeans.add(new Error ("Either CODE or OBJECT parameter must be specified in tag MLET")); 604 continue; 605 } 606 try { 607 if (code != null) { 608 609 Vector signat = new Vector (); 610 Vector pars = new Vector (); 611 612 for (Iterator p = attributes.keySet().iterator(); p.hasNext(); ) { 613 String param_name = (String ) p.next(); 614 if (param_name.equals("types")) { 615 signat = (Vector )elmt.getParameter(param_name); 616 } 617 if (param_name.equals("values")) { 618 pars = (Vector )elmt.getParameter(param_name); 619 } 620 } 621 622 for (int i = 0; i < signat.size(); i++) { 623 pars.setElementAt(constructParameter((String )pars.elementAt(i), (String )signat.elementAt(i)), i); 624 } 625 if (signat.isEmpty()) { 626 if (name == null) { 627 objInst = server.createMBean(code, null, mletObjectName); 628 } else { 629 objInst = server.createMBean(code, new ObjectName (name), mletObjectName); 630 } 631 } else { 632 Object [] parms = pars.toArray(); 633 String [] signature = new String [signat.size()]; 634 for (int i=0;i<signature.length;i++) { 635 signature[i] = (String ) signat.elementAt(i); 636 } 637 if (isDebugOn()) { 638 for (int i=0;i<signature.length;i++) { 639 debug(mth, "Signature = " + signature[i]); 640 debug(mth, "Params = " + parms[i].toString()); 641 } 642 } 643 if (name == null) { 644 objInst = server.createMBean(code, null, mletObjectName, parms, signature); 645 } else { 646 objInst = server.createMBean(code, new ObjectName (name), mletObjectName, parms, signature); 647 } 648 } 649 } else { 650 o = loadSerializedObject(codebase,serName); 651 if (name == null) { 652 server.registerMBean(o, null); 653 } else { 654 server.registerMBean(o, new ObjectName (name)); 655 } 656 objInst = new ObjectInstance (name, o.getClass().getName()); 657 } 658 } catch (ReflectionException ex) { 659 if (isTraceOn()) { 660 trace(mth, "ReflectionException: " + ex.getMessage()); 661 } 662 mbeans.add(ex); 663 continue; 664 } catch (InstanceAlreadyExistsException ex) { 665 if (isTraceOn()) { 666 trace(mth, "InstanceAlreadyExistsException: " + ex.getMessage()); 667 } 668 mbeans.add(ex); 669 continue; 670 } catch (MBeanRegistrationException ex) { 671 if (isTraceOn()) { 672 trace(mth, "MBeanRegistrationException: " + ex.getMessage()); 673 } 674 mbeans.add(ex); 675 continue; 676 } catch (MBeanException ex) { 677 if (isTraceOn()) { 678 trace(mth, "MBeanException: " + ex.getMessage()); 679 } 680 mbeans.add(ex); 681 continue; 682 } catch (NotCompliantMBeanException ex) { 683 if (isTraceOn()) { 684 trace(mth, "NotCompliantMBeanException: " + ex.getMessage()); 685 } 686 mbeans.add(ex); 687 continue; 688 } catch (InstanceNotFoundException ex) { 689 if (isTraceOn()) { 690 trace(mth, "InstanceNotFoundException: " + ex.getMessage()); 691 } 692 mbeans.add(ex); 693 continue; 694 } catch (IOException ex) { 695 if (isTraceOn()) { 696 trace(mth, "IOException: " + ex.getMessage()); 697 } 698 mbeans.add(ex); 699 continue; 700 } catch (SecurityException ex) { 701 if (isTraceOn()) { 702 trace(mth, "SecurityException: " + ex.getMessage()); 703 } 704 mbeans.add(ex); 705 continue; 706 } catch (Exception ex) { 707 if (isTraceOn()) { 708 trace(mth, "Exception: " + ex.getClass().getName() + ex.getMessage()); 709 } 710 mbeans.add(ex); 711 continue; 712 } catch (Error ex) { 713 if (isTraceOn()) { 714 trace(mth, "Error: " + ex.getMessage()); 715 } 716 mbeans.add(ex); 717 continue; 718 } 719 mbeans.add(objInst); 720 } 721 return mbeans; 722 } 723 724 732 public String getLibraryDirectory() { 733 return libraryDirectory; 734 } 735 736 744 public void setLibraryDirectory(String libdir) { 745 libraryDirectory = libdir; 746 } 747 748 762 public ObjectName preRegister(MBeanServer server, ObjectName name) throws java.lang.Exception { 763 764 setMBeanServer(server); 766 767 if (name == null) { 769 name = new ObjectName (server.getDefaultDomain() + ":" + ServiceName.MLET); 770 } 771 772 this.mletObjectName = name; 773 return this.mletObjectName; 774 } 775 776 785 public void postRegister (Boolean registrationDone) { 786 } 787 788 795 public void preDeregister() throws java.lang.Exception { 796 } 797 798 799 803 public void postDeregister() { 804 } 805 806 824 public void writeExternal(ObjectOutput out) 825 throws IOException , UnsupportedOperationException { 826 throw new UnsupportedOperationException ("MLet.writeExternal"); 827 } 828 829 849 public void readExternal(ObjectInput in) 850 throws IOException , ClassNotFoundException , 851 UnsupportedOperationException { 852 throw new UnsupportedOperationException ("MLet.readExternal"); 853 } 854 855 860 861 879 public synchronized Class loadClass(String name, 880 ClassLoaderRepository clr) 881 throws ClassNotFoundException { 882 final ClassLoaderRepository before=currentClr; 883 try { 884 currentClr = clr; 885 final Class c = loadClass(name); 886 return c; 887 } finally { 888 currentClr = before; 889 } 890 } 891 892 897 898 908 protected Class findClass(String name) throws ClassNotFoundException { 909 914 return findClass(name, currentClr); 915 } 916 917 929 Class findClass(String name, ClassLoaderRepository clr) 930 throws ClassNotFoundException { 931 Class c = null; 932 if (isTraceOn()) { 933 trace("findClass", name); 934 } 935 try { 937 c = super.findClass(name); 938 if (isTraceOn()) { 939 trace("findClass", "Class "+name+ 940 " loaded through mlet classloader"); 941 } 942 } catch (ClassNotFoundException e) { 943 debug("findClass", "Class "+name+ " not found locally."); 945 } 946 if (c == null && delegateToCLR && clr != null) { 948 try { 951 debug("findClass", "Class "+name+": looking in CLR"); 952 c = clr.loadClassBefore(this, name); 953 if (isTraceOn()) { 956 trace("findClass", "Class "+name+ 957 " loaded through the default classloader repository"); 958 } 959 } catch (ClassNotFoundException e) { 960 debug("findClass", "Class "+name+ " not found in CLR."); 961 } 963 } 964 if (c == null) { 965 debug("findClass","Failed to load class " + name); 966 throw new ClassNotFoundException (name); 967 } 968 return c; 969 } 970 971 996 protected String findLibrary(String libname) { 997 998 String abs_path; 999 String mth = "findLibrary"; 1000 1001 String nativelibname = System.mapLibraryName(libname); 1004 1005 if (isTraceOn()) { 1009 trace(mth, "Search " + libname + " in all JAR files."); 1010 } 1011 1012 if (isTraceOn()) { 1017 trace(mth, "loadLibraryAsResource(" + nativelibname + ")"); 1018 } 1019 abs_path = loadLibraryAsResource(nativelibname); 1020 if (abs_path != null) { 1021 if (isTraceOn()) { 1022 trace(mth, nativelibname + " loaded " + "absolute path = " + abs_path); 1023 } 1024 return abs_path; 1025 } 1026 1027 nativelibname = removeSpace(System.getProperty("os.name")) + File.separator + 1032 removeSpace(System.getProperty("os.arch")) + File.separator + 1033 removeSpace(System.getProperty("os.version")) + File.separator + 1034 "lib" + File.separator + nativelibname; 1035 if (isTraceOn()) { 1036 trace(mth, "loadLibraryAsResource(" + nativelibname + ")"); 1037 } 1038 1039 abs_path = loadLibraryAsResource(nativelibname); 1040 if (abs_path != null) { 1041 if (isTraceOn()) { 1042 trace(mth, nativelibname + " loaded " + "absolute path = " + abs_path); 1043 } 1044 return abs_path; 1045 } 1046 1047 1051 if (isTraceOn()) { 1052 trace(mth, libname + " not found in any JAR file."); 1053 trace(mth, "Search " + libname + " along the path specified as the java.library.path property."); 1054 } 1055 1056 1057 return null; 1061 } 1062 1063 1064 1069 1070 private String getTmpDir() { 1071 String tmpDir = (String )System.getProperty("java.io.tmpdir"); 1073 if (tmpDir != null) return tmpDir; 1074 1075 File tmpFile = null; 1077 try { 1078 tmpFile = File.createTempFile("tmp","jmx"); 1080 if (tmpFile == null) return null; 1081 final File tmpDirFile = tmpFile.getParentFile(); 1082 if (tmpDirFile == null) return null; 1083 return tmpDirFile.getAbsolutePath(); 1084 } catch (Exception x) { 1085 debug("getTmpDir","Failed to determine system temporary dir."); 1086 return null; 1087 } finally { 1088 if (tmpFile!=null) try { 1090 tmpFile.delete(); 1091 } catch (Exception x) { 1092 debug("getTmpDir","Failed to delete temporary file: " + x.getMessage()); 1093 } 1094 } 1095 } 1096 1097 1102 private synchronized String loadLibraryAsResource(String libname) { 1103 try { 1104 InputStream is = getResourceAsStream(libname.replace(File.separatorChar,'/')); 1105 if (is != null) { 1106 File directory = new File (libraryDirectory); 1107 directory.mkdirs(); 1108 File file = File.createTempFile(libname + ".", null, directory); 1109 file.deleteOnExit(); 1110 FileOutputStream fileOutput = new FileOutputStream (file); 1111 int c; 1112 while ((c = is.read()) != -1) { 1113 fileOutput.write(c); 1114 } 1115 is.close(); 1116 fileOutput.close(); 1117 if (file.exists()) { 1118 return file.getAbsolutePath(); 1119 } 1120 } 1121 } catch (Exception e) { 1122 debug("loadLibraryAsResource",libname+ 1123 ": Failed to load library. " + e); 1124 return null; 1125 } 1126 return null; 1127 } 1128 1129 1133 private String removeSpace(String s) { 1134 s = s.trim(); 1135 int j = s.indexOf(' '); 1136 if (j == -1) { 1137 return s; 1138 } 1139 String temp = ""; 1140 int k = 0; 1141 while (j != -1) { 1142 s = s.substring(k); 1143 j = s.indexOf(' '); 1144 if (j != -1) { 1145 temp = temp + s.substring(0, j); 1146 } else { 1147 temp = temp + s.substring(0); 1148 } 1149 k = j + 1; 1150 } 1151 return temp; 1152 } 1153 1154 1181 protected URL check(String version, URL codebase, String jarfile, 1182 MLetContent mlet) 1183 throws Exception { 1184 return codebase; 1185 } 1186 1187 1197 private Object loadSerializedObject(URL codebase, String filename) throws IOException , ClassNotFoundException { 1198 if (filename != null) { 1199 filename = filename.replace(File.separatorChar,'/'); 1200 } 1201 if (isTraceOn()) { 1202 trace("loadSerializedObject", codebase.toString() + filename); 1203 } 1204 InputStream is = getResourceAsStream(filename); 1205 if (is != null) { 1206 try { 1207 ObjectInputStream ois = new MLetObjectInputStream (is, this); 1208 Object serObject = ois.readObject(); 1209 ois.close(); 1210 return serObject; 1211 } catch (IOException e) { 1212 if (isDebugOn()) { 1213 debug("loadSerializedObject", "Exception while deserializing " + filename + ", " + e.getMessage()); 1214 } 1215 throw e; 1216 } catch (ClassNotFoundException e) { 1217 if (isDebugOn()) { 1218 debug("loadSerializedObject", "Exception while deserializing " + filename + ", " + e.getMessage()); 1219 } 1220 throw e; 1221 } 1222 } else { 1223 if (isDebugOn()) { 1224 debug("loadSerializedObject", "Error: File " + filename + " containing serialized object not found"); 1225 } 1226 throw new Error ("File " + filename + " containing serialized object not found"); 1227 } 1228 } 1229 1230 1234 private Object constructParameter(String param, String type) { 1235 Class c = (Class ) primitiveClasses.get(type); 1237 if (c != null) { 1238 try { 1239 Constructor cons = 1240 c.getConstructor(new Class [] {String .class}); 1241 Object [] oo = new Object [1]; 1242 oo[0]=param; 1243 return(cons.newInstance(oo)); 1244 1245 } catch (Exception e) { 1246 if (isDebugOn()) { 1247 debug(dbgTag, "constructParameter", "Unexpected Exception" + e.getClass().getName() + " occured"); 1248 } 1249 } 1250 } 1251 if (type.compareTo("java.lang.Boolean") == 0) 1252 return new Boolean (param); 1253 if (type.compareTo("java.lang.Byte") == 0) 1254 return new Byte (param); 1255 if (type.compareTo("java.lang.Short") == 0) 1256 return new Short (param); 1257 if (type.compareTo("java.lang.Long") == 0) 1258 return new Long (param); 1259 if (type.compareTo("java.lang.Integer") == 0) 1260 return new Integer (param); 1261 if (type.compareTo("java.lang.Float") == 0) 1262 return new Float (param); 1263 if (type.compareTo("java.lang.Double") == 0) 1264 return new Double (param); 1265 if (type.compareTo("java.lang.String") == 0) 1266 return param; 1267 1268 return param; 1269 } 1270 1271 private synchronized void setMBeanServer(final MBeanServer server) { 1272 this.server = server; 1273 currentClr = (ClassLoaderRepository ) 1274 AccessController.doPrivileged(new PrivilegedAction () { 1275 public Object run() { 1276 return server.getClassLoaderRepository(); 1277 } 1278 }); 1279 } 1280 1281 1284 private boolean isTraceOn() { 1285 return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_MLET); 1286 } 1287 1288 private void trace(String clz, String func, String info) { 1289 Trace.send(Trace.LEVEL_TRACE, Trace.INFO_MLET, clz, func, info); 1290 } 1291 1292 private void trace(String func, String info) { 1293 trace(dbgTag, func, info); 1294 } 1295 1296 private boolean isDebugOn() { 1297 return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_MLET); 1298 } 1299 1300 private void debug(String clz, String func, String info) { 1301 Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_MLET, clz, func, info); 1302 } 1303 1304 private void debug(String func, String info) { 1305 debug(dbgTag, func, info); 1306 } 1307 } 1308 | Popular Tags |