001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 package org.apache.felix.framework.util; 020 021 import java.io.*; 022 import java.lang.reflect.*; 023 import java.net.*; 024 import java.security.*; 025 import java.util.HashMap; 026 import java.util.Hashtable; 027 028 import org.osgi.framework.BundleActivator; 029 import org.osgi.framework.BundleContext; 030 031 /** 032 * <p> 033 * This is a utility class to centralize all action that should be performed 034 * in a <tt>doPrivileged()</tt> block. To perform a secure action, simply 035 * create an instance of this class and use the specific method to perform 036 * the desired action. When an instance is created, this class will capture 037 * the security context and will then use that context when checking for 038 * permission to perform the action. Instances of this class should not be 039 * passed around since they may grant the receiver a capability to perform 040 * privileged actions. 041 * </p> 042 **/ 043 public class SecureAction 044 { 045 private static final ThreadLocal m_actions = new ThreadLocal() 046 { 047 public Object initialValue() 048 { 049 return new Actions(); 050 } 051 }; 052 053 protected static transient int BUFSIZE = 4096; 054 055 private AccessControlContext m_acc = null; 056 057 public SecureAction() 058 { 059 if (System.getSecurityManager() != null) 060 { 061 try 062 { 063 Actions actions = (Actions) m_actions.get(); 064 actions.set(Actions.INITIALIZE_CONTEXT, null); 065 m_acc = (AccessControlContext) AccessController.doPrivileged(actions); 066 } 067 catch (PrivilegedActionException ex) 068 { 069 throw (RuntimeException) ex.getException(); 070 } 071 } 072 else 073 { 074 m_acc = AccessController.getContext(); 075 } 076 } 077 078 public String getSystemProperty(String name, String def) 079 { 080 if (System.getSecurityManager() != null) 081 { 082 try 083 { 084 Actions actions = (Actions) m_actions.get(); 085 actions.set(Actions.GET_PROPERTY_ACTION, name, def); 086 return (String) AccessController.doPrivileged(actions, m_acc); 087 } 088 catch (PrivilegedActionException ex) 089 { 090 throw (RuntimeException) ex.getException(); 091 } 092 } 093 else 094 { 095 return System.getProperty(name, def); 096 } 097 } 098 099 public ClassLoader getParentClassLoader(ClassLoader loader) 100 { 101 if (System.getSecurityManager() != null) 102 { 103 try 104 { 105 Actions actions = (Actions) m_actions.get(); 106 actions.set(Actions.GET_PARENT_CLASS_LOADER_ACTION, loader); 107 return (ClassLoader) AccessController.doPrivileged(actions, m_acc); 108 } 109 catch (PrivilegedActionException ex) 110 { 111 throw (RuntimeException) ex.getException(); 112 } 113 } 114 else 115 { 116 return loader.getParent(); 117 } 118 } 119 120 public ClassLoader getSystemClassLoader() 121 { 122 if (System.getSecurityManager() != null) 123 { 124 try 125 { 126 Actions actions = (Actions) m_actions.get(); 127 actions.set(Actions.GET_SYSTEM_CLASS_LOADER_ACTION); 128 return (ClassLoader) AccessController.doPrivileged(actions, m_acc); 129 } 130 catch (PrivilegedActionException ex) 131 { 132 throw (RuntimeException) ex.getException(); 133 } 134 } 135 else 136 { 137 return ClassLoader.getSystemClassLoader(); 138 } 139 } 140 141 public ClassLoader getClassLoader(Class clazz) 142 { 143 if (System.getSecurityManager() != null) 144 { 145 try 146 { 147 Actions actions = (Actions) m_actions.get(); 148 actions.set(Actions.GET_CLASS_LOADER_ACTION, clazz); 149 return (ClassLoader) AccessController.doPrivileged(actions, m_acc); 150 } 151 catch (PrivilegedActionException ex) 152 { 153 throw (RuntimeException) ex.getException(); 154 } 155 } 156 else 157 { 158 return clazz.getClassLoader(); 159 } 160 } 161 162 public Class forName(String name) throws ClassNotFoundException 163 { 164 if (System.getSecurityManager() != null) 165 { 166 try 167 { 168 Actions actions = (Actions) m_actions.get(); 169 actions.set(Actions.FOR_NAME_ACTION, name); 170 return (Class) AccessController.doPrivileged(actions, m_acc); 171 } 172 catch (PrivilegedActionException ex) 173 { 174 if (ex.getException() instanceof ClassNotFoundException) 175 { 176 throw (ClassNotFoundException) ex.getException(); 177 } 178 throw (RuntimeException) ex.getException(); 179 } 180 } 181 else 182 { 183 return Class.forName(name); 184 } 185 } 186 187 public URL createURL(String protocol, String host, 188 int port, String path, URLStreamHandler handler) 189 throws MalformedURLException 190 { 191 if (System.getSecurityManager() != null) 192 { 193 try 194 { 195 Actions actions = (Actions) m_actions.get(); 196 actions.set(Actions.CREATE_URL_ACTION, protocol, host, 197 new Integer(port), path, handler); 198 return (URL) AccessController.doPrivileged(actions, m_acc); 199 } 200 catch (PrivilegedActionException ex) 201 { 202 if (ex.getException() instanceof MalformedURLException) 203 { 204 throw (MalformedURLException) ex.getException(); 205 } 206 throw (RuntimeException) ex.getException(); 207 } 208 } 209 else 210 { 211 return new URL(protocol, host, port, path, handler); 212 } 213 } 214 215 public URL createURL(URL context, String spec, URLStreamHandler handler) 216 throws MalformedURLException 217 { 218 if (System.getSecurityManager() != null) 219 { 220 try 221 { 222 Actions actions = (Actions) m_actions.get(); 223 actions.set(Actions.CREATE_URL_WITH_CONTEXT_ACTION, context, 224 spec, handler); 225 return (URL) AccessController.doPrivileged(actions, m_acc); 226 } 227 catch (PrivilegedActionException ex) 228 { 229 if (ex.getException() instanceof MalformedURLException) 230 { 231 throw (MalformedURLException) ex.getException(); 232 } 233 throw (RuntimeException) ex.getException(); 234 } 235 } 236 else 237 { 238 return new URL(context, spec, handler); 239 } 240 } 241 242 public Process exec(String command) throws IOException 243 { 244 if (System.getSecurityManager() != null) 245 { 246 try 247 { 248 Actions actions = (Actions) m_actions.get(); 249 actions.set(Actions.EXEC_ACTION, command); 250 return (Process) AccessController.doPrivileged(actions, m_acc); 251 } 252 catch (PrivilegedActionException ex) 253 { 254 throw (RuntimeException) ex.getException(); 255 } 256 } 257 else 258 { 259 return Runtime.getRuntime().exec(command); 260 } 261 } 262 263 public String getAbsolutePath(File file) 264 { 265 if (System.getSecurityManager() != null) 266 { 267 try 268 { 269 Actions actions = (Actions) m_actions.get(); 270 actions.set(Actions.GET_ABSOLUTE_PATH_ACTION, file); 271 return (String) AccessController.doPrivileged(actions, m_acc); 272 } 273 catch (PrivilegedActionException ex) 274 { 275 throw (RuntimeException) ex.getException(); 276 } 277 } 278 else 279 { 280 return file.getAbsolutePath(); 281 } 282 } 283 284 public boolean fileExists(File file) 285 { 286 if (System.getSecurityManager() != null) 287 { 288 try 289 { 290 Actions actions = (Actions) m_actions.get(); 291 actions.set(Actions.FILE_EXISTS_ACTION, file); 292 return ((Boolean) AccessController.doPrivileged(actions, m_acc)) 293 .booleanValue(); 294 } 295 catch (PrivilegedActionException ex) 296 { 297 throw (RuntimeException) ex.getException(); 298 } 299 } 300 else 301 { 302 return file.exists(); 303 } 304 } 305 306 public boolean isFileDirectory(File file) 307 { 308 if (System.getSecurityManager() != null) 309 { 310 try 311 { 312 Actions actions = (Actions) m_actions.get(); 313 actions.set(Actions.FILE_IS_DIRECTORY_ACTION, file); 314 return ((Boolean) AccessController.doPrivileged(actions, m_acc)) 315 .booleanValue(); 316 } 317 catch (PrivilegedActionException ex) 318 { 319 throw (RuntimeException) ex.getException(); 320 } 321 } 322 else 323 { 324 return file.isDirectory(); 325 } 326 } 327 328 public boolean mkdir(File file) 329 { 330 if (System.getSecurityManager() != null) 331 { 332 try 333 { 334 Actions actions = (Actions) m_actions.get(); 335 actions.set(Actions.MAKE_DIRECTORY_ACTION, file); 336 return ((Boolean) AccessController.doPrivileged(actions, m_acc)) 337 .booleanValue(); 338 } 339 catch (PrivilegedActionException ex) 340 { 341 throw (RuntimeException) ex.getException(); 342 } 343 } 344 else 345 { 346 return file.mkdir(); 347 } 348 } 349 350 public boolean mkdirs(File file) 351 { 352 if (System.getSecurityManager() != null) 353 { 354 try 355 { 356 Actions actions = (Actions) m_actions.get(); 357 actions.set(Actions.MAKE_DIRECTORIES_ACTION, file); 358 return ((Boolean) AccessController.doPrivileged(actions, m_acc)) 359 .booleanValue(); 360 } 361 catch (PrivilegedActionException ex) 362 { 363 throw (RuntimeException) ex.getException(); 364 } 365 } 366 else 367 { 368 return file.mkdirs(); 369 } 370 } 371 372 public File[] listDirectory(File file) 373 { 374 if (System.getSecurityManager() != null) 375 { 376 try 377 { 378 Actions actions = (Actions) m_actions.get(); 379 actions.set(Actions.LIST_DIRECTORY_ACTION, file); 380 return (File[]) AccessController.doPrivileged(actions, m_acc); 381 } 382 catch (PrivilegedActionException ex) 383 { 384 throw (RuntimeException) ex.getException(); 385 } 386 } 387 else 388 { 389 return file.listFiles(); 390 } 391 } 392 393 public boolean renameFile(File oldFile, File newFile) 394 { 395 if (System.getSecurityManager() != null) 396 { 397 try 398 { 399 Actions actions = (Actions) m_actions.get(); 400 actions.set(Actions.RENAME_FILE_ACTION, oldFile, newFile); 401 return ((Boolean) AccessController.doPrivileged(actions, m_acc)) 402 .booleanValue(); 403 } 404 catch (PrivilegedActionException ex) 405 { 406 throw (RuntimeException) ex.getException(); 407 } 408 } 409 else 410 { 411 return oldFile.renameTo(newFile); 412 } 413 } 414 415 public InputStream getFileInputStream(File file) throws IOException 416 { 417 if (System.getSecurityManager() != null) 418 { 419 try 420 { 421 Actions actions = (Actions) m_actions.get(); 422 actions.set(Actions.GET_FILE_INPUT_ACTION, file); 423 return (InputStream) AccessController.doPrivileged(actions, m_acc); 424 } 425 catch (PrivilegedActionException ex) 426 { 427 if (ex.getException() instanceof IOException) 428 { 429 throw (IOException) ex.getException(); 430 } 431 throw (RuntimeException) ex.getException(); 432 } 433 } 434 else 435 { 436 return new FileInputStream(file); 437 } 438 } 439 440 public OutputStream getFileOutputStream(File file) throws IOException 441 { 442 if (System.getSecurityManager() != null) 443 { 444 try 445 { 446 Actions actions = (Actions) m_actions.get(); 447 actions.set(Actions.GET_FILE_OUTPUT_ACTION, file); 448 return (OutputStream) AccessController.doPrivileged(actions, m_acc); 449 } 450 catch (PrivilegedActionException ex) 451 { 452 if (ex.getException() instanceof IOException) 453 { 454 throw (IOException) ex.getException(); 455 } 456 throw (RuntimeException) ex.getException(); 457 } 458 } 459 else 460 { 461 return new FileOutputStream(file); 462 } 463 } 464 465 public InputStream getURLConnectionInputStream(URLConnection conn) 466 throws IOException 467 { 468 if (System.getSecurityManager() != null) 469 { 470 try 471 { 472 Actions actions = (Actions) m_actions.get(); 473 actions.set(Actions.GET_URL_INPUT_ACTION, conn); 474 return (InputStream) AccessController.doPrivileged(actions, m_acc); 475 } 476 catch (PrivilegedActionException ex) 477 { 478 if (ex.getException() instanceof IOException) 479 { 480 throw (IOException) ex.getException(); 481 } 482 throw (RuntimeException) ex.getException(); 483 } 484 } 485 else 486 { 487 return conn.getInputStream(); 488 } 489 } 490 491 public boolean deleteFile(File target) 492 { 493 if (System.getSecurityManager() != null) 494 { 495 try 496 { 497 Actions actions = (Actions) m_actions.get(); 498 actions.set(Actions.DELETE_FILE_ACTION, target); 499 return ((Boolean) AccessController.doPrivileged(actions, m_acc)) 500 .booleanValue(); 501 } 502 catch (PrivilegedActionException ex) 503 { 504 throw (RuntimeException) ex.getException(); 505 } 506 } 507 else 508 { 509 return target.delete(); 510 } 511 } 512 513 public File createTempFile(String prefix, String suffix, File dir) 514 throws IOException 515 { 516 if (System.getSecurityManager() != null) 517 { 518 try 519 { 520 Actions actions = (Actions) m_actions.get(); 521 actions.set(Actions.CREATE_TMPFILE_ACTION, prefix, suffix, dir); 522 return (File) AccessController.doPrivileged(actions, m_acc); 523 } 524 catch (PrivilegedActionException ex) 525 { 526 if (ex.getException() instanceof IOException) 527 { 528 throw (IOException) ex.getException(); 529 } 530 throw (RuntimeException) ex.getException(); 531 } 532 } 533 else 534 { 535 return File.createTempFile(prefix, suffix, dir); 536 } 537 } 538 539 public URLConnection openURLConnection(URL url) throws IOException 540 { 541 if (System.getSecurityManager() != null) 542 { 543 try 544 { 545 Actions actions = (Actions) m_actions.get(); 546 actions.set(Actions.OPEN_URLCONNECTION_ACTION, url); 547 return (URLConnection) AccessController.doPrivileged(actions, 548 m_acc); 549 } 550 catch (PrivilegedActionException ex) 551 { 552 if (ex.getException() instanceof IOException) 553 { 554 throw (IOException) ex.getException(); 555 } 556 throw (RuntimeException) ex.getException(); 557 } 558 } 559 else 560 { 561 return url.openConnection(); 562 } 563 } 564 565 public JarFileX openJAR(File file) throws IOException 566 { 567 if (System.getSecurityManager() != null) 568 { 569 try 570 { 571 Actions actions = (Actions) m_actions.get(); 572 actions.set(Actions.OPEN_JARX_ACTION, file); 573 return (JarFileX) AccessController.doPrivileged(actions, m_acc); 574 } 575 catch (PrivilegedActionException ex) 576 { 577 if (ex.getException() instanceof IOException) 578 { 579 throw (IOException) ex.getException(); 580 } 581 throw (RuntimeException) ex.getException(); 582 } 583 } 584 else 585 { 586 return new JarFileX(file); 587 } 588 } 589 590 public JarFileX openJAR(File file, boolean verify) throws IOException 591 { 592 if (System.getSecurityManager() != null) 593 { 594 try 595 { 596 Actions actions = (Actions) m_actions.get(); 597 actions.set(Actions.OPEN_JARX_VERIFY_ACTION, file, (verify ? Boolean.TRUE : Boolean.FALSE)); 598 return (JarFileX) AccessController.doPrivileged(actions, m_acc); 599 } 600 catch (PrivilegedActionException ex) 601 { 602 if (ex.getException() instanceof IOException) 603 { 604 throw (IOException) ex.getException(); 605 } 606 throw (RuntimeException) ex.getException(); 607 } 608 } 609 else 610 { 611 return new JarFileX(file, verify); 612 } 613 } 614 // TODO: REFACTOR - SecureAction fix needed. 615 /* 616 public ModuleClassLoader createModuleClassLoader(ModuleImpl impl) 617 { 618 return createModuleClassLoader(impl, null); 619 } 620 621 public ModuleClassLoader createModuleClassLoader(ModuleImpl impl, 622 ProtectionDomain protectionDomain) 623 { 624 if (System.getSecurityManager() != null) 625 { 626 try 627 { 628 Actions actions = (Actions) m_actions.get(); 629 actions.set(Actions.CREATE_MODULECLASSLOADER_ACTION, impl, protectionDomain); 630 return (ModuleClassLoader) AccessController.doPrivileged(actions, m_acc); 631 } 632 catch (PrivilegedActionException ex) 633 { 634 throw (RuntimeException) ex.getException(); 635 } 636 } 637 else 638 { 639 return new ModuleClassLoader(impl, protectionDomain); 640 } 641 } 642 */ 643 public void startActivator(BundleActivator activator, BundleContext context) 644 throws Exception 645 { 646 if (System.getSecurityManager() != null) 647 { 648 try 649 { 650 Actions actions = (Actions) m_actions.get(); 651 actions.set(Actions.START_ACTIVATOR_ACTION, activator, context); 652 AccessController.doPrivileged(actions, m_acc); 653 } 654 catch (PrivilegedActionException ex) 655 { 656 throw ex.getException(); 657 } 658 } 659 else 660 { 661 activator.start(context); 662 } 663 } 664 665 public void stopActivator(BundleActivator activator, BundleContext context) 666 throws Exception 667 { 668 if (System.getSecurityManager() != null) 669 { 670 try 671 { 672 Actions actions = (Actions) m_actions.get(); 673 actions.set(Actions.STOP_ACTIVATOR_ACTION, activator, context); 674 AccessController.doPrivileged(actions, m_acc); 675 } 676 catch (PrivilegedActionException ex) 677 { 678 throw ex.getException(); 679 } 680 } 681 else 682 { 683 activator.stop(context); 684 } 685 } 686 687 public Policy getPolicy() 688 { 689 if (System.getSecurityManager() != null) 690 { 691 try 692 { 693 Actions actions = (Actions) m_actions.get(); 694 actions.set(Actions.GET_POLICY_ACTION, null); 695 return (Policy) AccessController.doPrivileged(actions, m_acc); 696 } 697 catch (PrivilegedActionException ex) 698 { 699 throw (RuntimeException) ex.getException(); 700 } 701 } 702 else 703 { 704 return Policy.getPolicy(); 705 } 706 } 707 708 public void addURLToURLClassLoader(URL extension, ClassLoader loader) throws Exception 709 { 710 if (System.getSecurityManager() != null) 711 { 712 Actions actions = (Actions) m_actions.get(); 713 actions.set(Actions.ADD_EXTENSION_URL, extension, loader); 714 try 715 { 716 AccessController.doPrivileged(actions, m_acc); 717 } 718 catch (PrivilegedActionException e) 719 { 720 throw e.getException(); 721 } 722 } 723 else 724 { 725 Method addURL = 726 URLClassLoader.class.getDeclaredMethod("addURL", 727 new Class[] {URL.class}); 728 addURL.setAccessible(true); 729 addURL.invoke(loader, new Object[]{extension}); 730 } 731 } 732 733 public Constructor getConstructor(Class target, Class[] types) throws Exception 734 { 735 if (System.getSecurityManager() != null) 736 { 737 Actions actions = (Actions) m_actions.get(); 738 actions.set(Actions.GET_CONSTRUCTOR_ACTION, target, types); 739 try 740 { 741 return (Constructor) AccessController.doPrivileged(actions, m_acc); 742 } 743 catch (PrivilegedActionException e) 744 { 745 throw e.getException(); 746 } 747 } 748 else 749 { 750 return target.getConstructor(types); 751 } 752 } 753 754 public Constructor getDeclaredConstructor(Class target, Class[] types) throws Exception 755 { 756 if (System.getSecurityManager() != null) 757 { 758 Actions actions = (Actions) m_actions.get(); 759 actions.set(Actions.GET_DECLARED_CONSTRUCTOR_ACTION, target, types); 760 try 761 { 762 return (Constructor) AccessController.doPrivileged(actions, m_acc); 763 } 764 catch (PrivilegedActionException e) 765 { 766 throw e.getException(); 767 } 768 } 769 else 770 { 771 return target.getDeclaredConstructor(types); 772 } 773 } 774 775 public Method getMethod(Class target, String method, Class[] types) throws Exception 776 { 777 if (System.getSecurityManager() != null) 778 { 779 Actions actions = (Actions) m_actions.get(); 780 actions.set(Actions.GET_METHOD_ACTION, target, method, types); 781 try 782 { 783 return (Method) AccessController.doPrivileged(actions, m_acc); 784 } 785 catch (PrivilegedActionException e) 786 { 787 throw e.getException(); 788 } 789 } 790 else 791 { 792 return target.getMethod(method, types); 793 } 794 } 795 796 public Method getDeclaredMethod(Class target, String method, Class[] types) throws Exception 797 { 798 if (System.getSecurityManager() != null) 799 { 800 Actions actions = (Actions) m_actions.get(); 801 actions.set(Actions.GET_DECLARED_METHOD_ACTION, target, method, types); 802 try 803 { 804 return (Method) AccessController.doPrivileged(actions, m_acc); 805 } 806 catch (PrivilegedActionException e) 807 { 808 throw e.getException(); 809 } 810 } 811 else 812 { 813 return target.getDeclaredMethod(method, types); 814 } 815 } 816 817 public void setAccesssible(AccessibleObject ao) 818 { 819 if (System.getSecurityManager() != null) 820 { 821 Actions actions = (Actions) m_actions.get(); 822 actions.set(Actions.SET_ACCESSIBLE_ACTION, ao); 823 try 824 { 825 AccessController.doPrivileged(actions, m_acc); 826 } 827 catch (PrivilegedActionException e) 828 { 829 throw (RuntimeException) e.getException(); 830 } 831 } 832 else 833 { 834 ao.setAccessible(true); 835 } 836 } 837 838 public Object invoke(Method method, Object target, Object[] params) throws Exception 839 { 840 if (System.getSecurityManager() != null) 841 { 842 Actions actions = (Actions) m_actions.get(); 843 actions.set(Actions.INVOKE_METHOD_ACTION, method, target, params); 844 try 845 { 846 return AccessController.doPrivileged(actions, m_acc); 847 } 848 catch (PrivilegedActionException e) 849 { 850 throw e.getException(); 851 } 852 } 853 else 854 { 855 method.setAccessible(true); 856 return method.invoke(target, params); 857 } 858 } 859 860 public Object invokeDirect(Method method, Object target, Object[] params) throws Exception 861 { 862 if (System.getSecurityManager() != null) 863 { 864 Actions actions = (Actions) m_actions.get(); 865 actions.set(Actions.INVOKE_DIRECTMETHOD_ACTION, method, target, params); 866 try 867 { 868 return AccessController.doPrivileged(actions, m_acc); 869 } 870 catch (PrivilegedActionException e) 871 { 872 throw e.getException(); 873 } 874 } 875 else 876 { 877 return method.invoke(target, params); 878 } 879 } 880 881 public Object invoke(Constructor constructor, Object[] params) throws Exception 882 { 883 if (System.getSecurityManager() != null) 884 { 885 Actions actions = (Actions) m_actions.get(); 886 actions.set(Actions.INVOKE_CONSTRUCTOR_ACTION, constructor, params); 887 try 888 { 889 return AccessController.doPrivileged(actions, m_acc); 890 } 891 catch (PrivilegedActionException e) 892 { 893 throw e.getException(); 894 } 895 } 896 else 897 { 898 return constructor.newInstance(params); 899 } 900 } 901 902 public Object getDeclaredField(Class targetClass, String name, Object target) 903 throws Exception 904 { 905 if (System.getSecurityManager() != null) 906 { 907 Actions actions = (Actions) m_actions.get(); 908 actions.set(Actions.GET_FIELD_ACTION, targetClass, name, target); 909 try 910 { 911 return AccessController.doPrivileged(actions, m_acc); 912 } 913 catch (PrivilegedActionException e) 914 { 915 throw e.getException(); 916 } 917 } 918 else 919 { 920 Field field = targetClass.getDeclaredField(name); 921 field.setAccessible(true); 922 923 return field.get(target); 924 } 925 } 926 927 public Object swapStaticFieldIfNotClass(Class targetClazz, 928 Class targetType, Class condition, String lockName) throws Exception 929 { 930 if (System.getSecurityManager() != null) 931 { 932 Actions actions = (Actions) m_actions.get(); 933 actions.set(Actions.SWAP_FIELD_ACTION, targetClazz, targetType, 934 condition, lockName); 935 try 936 { 937 return AccessController.doPrivileged(actions, m_acc); 938 } 939 catch (PrivilegedActionException e) 940 { 941 throw e.getException(); 942 } 943 } 944 else 945 { 946 return _swapStaticFieldIfNotClass(targetClazz, targetType, 947 condition, lockName); 948 } 949 } 950 951 private static Object _swapStaticFieldIfNotClass(Class targetClazz, 952 Class targetType, Class condition, String lockName) throws Exception 953 { 954 Object lock = null; 955 if (lockName != null) 956 { 957 try 958 { 959 Field lockField = 960 targetClazz.getDeclaredField(lockName); 961 lockField.setAccessible(true); 962 lock = lockField.get(null); 963 } 964 catch (NoSuchFieldException ex) 965 { 966 } 967 } 968 if (lock == null) 969 { 970 lock = targetClazz; 971 } 972 synchronized (lock) 973 { 974 Field[] fields = targetClazz.getDeclaredFields(); 975 976 Object result = null; 977 for (int i = 0; (i < fields.length) && (result == null); i++) 978 { 979 if (Modifier.isStatic(fields[i].getModifiers()) && 980 (fields[i].getType() == targetType)) 981 { 982 fields[i].setAccessible(true); 983 984 result = fields[i].get(null); 985 986 if (result != null) 987 { 988 if ((condition == null) || 989 !result.getClass().getName().equals(condition.getName())) 990 { 991 fields[i].set(null, null); 992 } 993 } 994 } 995 } 996 if (result != null) 997 { 998 if ((condition == null) || !result.getClass().getName().equals(condition.getName())) 999 { 1000 // reset cache 1001 for (int i = 0; i < fields.length; i++) 1002 { 1003 if (Modifier.isStatic(fields[i].getModifiers()) && 1004 (fields[i].getType() == Hashtable.class)) 1005 { 1006 fields[i].setAccessible(true); 1007 Hashtable cache = (Hashtable) fields[i].get(null); 1008 if (cache != null) 1009 { 1010 cache.clear(); 1011 } 1012 } 1013 } 1014 } 1015 return result; 1016 } 1017 } 1018 return null; 1019 } 1020 1021 public void flush(Class targetClazz, Object lock) throws Exception 1022 { 1023 if (System.getSecurityManager() != null) 1024 { 1025 Actions actions = (Actions) m_actions.get(); 1026 actions.set(Actions.FLUSH_FIELD_ACTION, targetClazz, lock); 1027 try 1028 { 1029 AccessController.doPrivileged(actions, m_acc); 1030 } 1031 catch (PrivilegedActionException e) 1032 { 1033 throw e.getException(); 1034 } 1035 } 1036 else 1037 { 1038 _flush(targetClazz, lock); 1039 } 1040 } 1041 1042 private static void _flush(Class targetClazz, Object lock) throws Exception 1043 { 1044 synchronized (lock) 1045 { 1046 Field[] fields = targetClazz.getDeclaredFields(); 1047 // reset cache 1048 for (int i = 0; i < fields.length; i++) 1049 { 1050 if (Modifier.isStatic(fields[i].getModifiers()) && 1051 ((fields[i].getType() == Hashtable.class) || (fields[i].getType() == HashMap.class))) 1052 { 1053 fields[i].setAccessible(true); 1054 if (fields[i].getType() == Hashtable.class) 1055 { 1056 Hashtable cache = (Hashtable) fields[i].get(null); 1057 if (cache != null) 1058 { 1059 cache.clear(); 1060 } 1061 } 1062 else 1063 { 1064 HashMap cache = (HashMap) fields[i].get(null); 1065 if (cache != null) 1066 { 1067 cache.clear(); 1068 } 1069 } 1070 } 1071 } 1072 } 1073 } 1074 1075 private static class Actions implements PrivilegedExceptionAction 1076 { 1077 public static final int INITIALIZE_CONTEXT = 0; 1078 1079 public static final int ADD_EXTENSION_URL = 1; 1080 public static final int CREATE_MODULECLASSLOADER_ACTION = 2; 1081 public static final int CREATE_TMPFILE_ACTION = 3; 1082 public static final int CREATE_URL_ACTION = 4; 1083 public static final int CREATE_URL_WITH_CONTEXT_ACTION = 5; 1084 public static final int DELETE_FILE_ACTION = 6; 1085 public static final int EXEC_ACTION = 7; 1086 public static final int FILE_EXISTS_ACTION = 8; 1087 public static final int FILE_IS_DIRECTORY_ACTION = 9; 1088 public static final int FOR_NAME_ACTION = 10; 1089 public static final int GET_ABSOLUTE_PATH_ACTION = 11; 1090 public static final int GET_CONSTRUCTOR_ACTION = 12; 1091 public static final int GET_DECLARED_CONSTRUCTOR_ACTION = 13; 1092 public static final int GET_DECLARED_METHOD_ACTION = 14; 1093 public static final int GET_FIELD_ACTION = 15; 1094 public static final int GET_FILE_INPUT_ACTION = 16; 1095 public static final int GET_FILE_OUTPUT_ACTION = 17; 1096 public static final int GET_METHOD_ACTION = 19; 1097 public static final int GET_POLICY_ACTION = 20; 1098 public static final int GET_PROPERTY_ACTION = 21; 1099 public static final int GET_PARENT_CLASS_LOADER_ACTION = 22; 1100 public static final int GET_SYSTEM_CLASS_LOADER_ACTION = 23; 1101 public static final int GET_URL_INPUT_ACTION = 24; 1102 public static final int INVOKE_CONSTRUCTOR_ACTION = 25; 1103 public static final int INVOKE_DIRECTMETHOD_ACTION = 26; 1104 public static final int INVOKE_METHOD_ACTION = 27; 1105 public static final int LIST_DIRECTORY_ACTION = 28; 1106 public static final int MAKE_DIRECTORIES_ACTION = 29; 1107 public static final int MAKE_DIRECTORY_ACTION = 30; 1108 public static final int OPEN_JARX_ACTION = 31; 1109 public static final int OPEN_JARX_VERIFY_ACTION = 32; 1110 public static final int OPEN_URLCONNECTION_ACTION = 33; 1111 public static final int RENAME_FILE_ACTION = 34; 1112 public static final int SET_ACCESSIBLE_ACTION = 35; 1113 public static final int START_ACTIVATOR_ACTION = 36; 1114 public static final int STOP_ACTIVATOR_ACTION = 37; 1115 public static final int SWAP_FIELD_ACTION = 38; 1116 public static final int SYSTEM_EXIT_ACTION = 39; 1117 public static final int FLUSH_FIELD_ACTION = 40; 1118 public static final int GET_CLASS_LOADER_ACTION = 41; 1119 1120 private int m_action = -1; 1121 private Object m_arg1 = null; 1122 private Object m_arg2 = null; 1123 private Object m_arg3 = null; 1124 private Object m_arg4 = null; 1125 private Object m_arg5 = null; 1126 1127 public void set(int action) 1128 { 1129 m_action = action; 1130 } 1131 1132 public void set(int action, Object arg1) 1133 { 1134 m_action = action; 1135 m_arg1 = arg1; 1136 } 1137 1138 public void set(int action, Object arg1, Object arg2) 1139 { 1140 m_action = action; 1141 m_arg1 = arg1; 1142 m_arg2 = arg2; 1143 } 1144 1145 public void set(int action, Object arg1, Object arg2, Object arg3) 1146 { 1147 m_action = action; 1148 m_arg1 = arg1; 1149 m_arg2 = arg2; 1150 m_arg3 = arg3; 1151 } 1152 1153 public void set(int action, Object arg1, Object arg2, Object arg3, 1154 Object arg4) 1155 { 1156 m_action = action; 1157 m_arg1 = arg1; 1158 m_arg2 = arg2; 1159 m_arg3 = arg3; 1160 m_arg4 = arg4; 1161 } 1162 1163 public void set(int action, Object arg1, Object arg2, Object arg3, 1164 Object arg4, Object arg5) 1165 { 1166 m_action = action; 1167 m_arg1 = arg1; 1168 m_arg2 = arg2; 1169 m_arg3 = arg3; 1170 m_arg4 = arg4; 1171 m_arg5 = arg5; 1172 } 1173 1174 private void unset() 1175 { 1176 m_action = -1; 1177 m_arg1 = null; 1178 m_arg2 = null; 1179 m_arg3 = null; 1180 m_arg4 = null; 1181 m_arg5 = null; 1182 } 1183 1184 public Object run() throws Exception 1185 { 1186 int action = m_action; 1187 Object arg1 = m_arg1; 1188 Object arg2 = m_arg2; 1189 Object arg3 = m_arg3; 1190 Object arg4 = m_arg4; 1191 Object arg5 = m_arg5; 1192 1193 unset(); 1194 1195 if (action == INITIALIZE_CONTEXT) 1196 { 1197 return AccessController.getContext(); 1198 } 1199 else if (action == GET_PROPERTY_ACTION) 1200 { 1201 return System.getProperty((String) arg1, (String) arg2); 1202 } 1203 else if (action == GET_PARENT_CLASS_LOADER_ACTION) 1204 { 1205 return ((ClassLoader) arg1).getParent(); 1206 } 1207 else if (action == GET_SYSTEM_CLASS_LOADER_ACTION) 1208 { 1209 return ClassLoader.getSystemClassLoader(); 1210 } 1211 else if (action == FOR_NAME_ACTION) 1212 { 1213 return Class.forName((String) arg1); 1214 } 1215 else if (action == CREATE_URL_ACTION) 1216 { 1217 return new URL((String) arg1, (String) arg2, 1218 ((Integer) arg3).intValue(), (String) arg4, 1219 (URLStreamHandler) arg5); 1220 } 1221 else if (action == CREATE_URL_WITH_CONTEXT_ACTION) 1222 { 1223 return new URL((URL) arg1, (String) arg2, 1224 (URLStreamHandler) arg3); 1225 } 1226 else if (action == EXEC_ACTION) 1227 { 1228 return Runtime.getRuntime().exec((String) arg1); 1229 } 1230 else if (action == GET_ABSOLUTE_PATH_ACTION) 1231 { 1232 return ((File) arg1).getAbsolutePath(); 1233 } 1234 else if (action == FILE_EXISTS_ACTION) 1235 { 1236 return ((File) arg1).exists() ? Boolean.TRUE : Boolean.FALSE; 1237 } 1238 else if (action == FILE_IS_DIRECTORY_ACTION) 1239 { 1240 return ((File) arg1).isDirectory() ? Boolean.TRUE : Boolean.FALSE; 1241 } 1242 else if (action == MAKE_DIRECTORY_ACTION) 1243 { 1244 return ((File) arg1).mkdir() ? Boolean.TRUE : Boolean.FALSE; 1245 } 1246 else if (action == MAKE_DIRECTORIES_ACTION) 1247 { 1248 return ((File) arg1).mkdirs() ? Boolean.TRUE : Boolean.FALSE; 1249 } 1250 else if (action == LIST_DIRECTORY_ACTION) 1251 { 1252 return ((File) arg1).listFiles(); 1253 } 1254 else if (action == RENAME_FILE_ACTION) 1255 { 1256 return ((File) arg1).renameTo((File) arg2) ? Boolean.TRUE : Boolean.FALSE; 1257 } 1258 else if (action == GET_FILE_INPUT_ACTION) 1259 { 1260 return new FileInputStream((File) arg1); 1261 } 1262 else if (action == GET_FILE_OUTPUT_ACTION) 1263 { 1264 return new FileOutputStream((File) arg1); 1265 } 1266 else if (action == DELETE_FILE_ACTION) 1267 { 1268 return ((File) arg1).delete() ? Boolean.TRUE : Boolean.FALSE; 1269 } 1270 else if (action == OPEN_JARX_ACTION) 1271 { 1272 return new JarFileX((File) arg1); 1273 } 1274 else if (action == OPEN_JARX_VERIFY_ACTION) 1275 { 1276 return new JarFileX((File) arg1, ((Boolean) arg2).booleanValue()); 1277 } 1278 else if (action == GET_URL_INPUT_ACTION) 1279 { 1280 return ((URLConnection) arg1).getInputStream(); 1281 } 1282 else if (action == START_ACTIVATOR_ACTION) 1283 { 1284 ((BundleActivator) arg1).start((BundleContext) arg2); 1285 return null; 1286 } 1287 else if (action == STOP_ACTIVATOR_ACTION) 1288 { 1289 ((BundleActivator) arg1).stop((BundleContext) arg2); 1290 return null; 1291 } 1292 else if (action == SYSTEM_EXIT_ACTION) 1293 { 1294 System.exit(((Integer) arg1).intValue()); 1295 } 1296 else if (action == GET_POLICY_ACTION) 1297 { 1298 return Policy.getPolicy(); 1299 } 1300 else if (action == CREATE_TMPFILE_ACTION) 1301 { 1302 return File.createTempFile((String) arg1, (String) arg2, 1303 (File) arg3); 1304 } 1305 else if (action == OPEN_URLCONNECTION_ACTION) 1306 { 1307 return ((URL) arg1).openConnection(); 1308 } 1309 else if (action == ADD_EXTENSION_URL) 1310 { 1311 Method addURL = 1312 URLClassLoader.class.getDeclaredMethod("addURL", 1313 new Class[] {URL.class}); 1314 addURL.setAccessible(true); 1315 addURL.invoke(arg2, new Object[]{arg1}); 1316 } 1317 else if (action == GET_CONSTRUCTOR_ACTION) 1318 { 1319 return ((Class) arg1).getConstructor((Class[]) arg2); 1320 } 1321 else if (action == GET_DECLARED_CONSTRUCTOR_ACTION) 1322 { 1323 return ((Class) arg1).getDeclaredConstructor((Class[]) arg2); 1324 } 1325 else if (action == GET_METHOD_ACTION) 1326 { 1327 return ((Class) arg1).getMethod((String) arg2, (Class[]) arg3); 1328 } 1329 else if (action == INVOKE_METHOD_ACTION) 1330 { 1331 ((Method) arg1).setAccessible(true); 1332 return ((Method) arg1).invoke(arg2, (Object[]) arg3); 1333 } 1334 else if (action == INVOKE_DIRECTMETHOD_ACTION) 1335 { 1336 return ((Method) arg1).invoke(arg2, (Object[]) arg3); 1337 } 1338 else if (action == INVOKE_CONSTRUCTOR_ACTION) 1339 { 1340 return ((Constructor) arg1).newInstance((Object[]) arg2); 1341 } 1342 else if (action == SWAP_FIELD_ACTION) 1343 { 1344 return _swapStaticFieldIfNotClass((Class) arg1, 1345 (Class) arg2, (Class) arg3, (String) arg4); 1346 } 1347 else if (action == GET_FIELD_ACTION) 1348 { 1349 Field field = ((Class) arg1).getDeclaredField((String) arg2); 1350 field.setAccessible(true); 1351 return field.get(arg3); 1352 } 1353 else if (action == GET_DECLARED_METHOD_ACTION) 1354 { 1355 return ((Class) arg1).getDeclaredMethod((String) arg2, (Class[]) arg3); 1356 } 1357 else if (action == SET_ACCESSIBLE_ACTION) 1358 { 1359 ((AccessibleObject) arg1).setAccessible(true); 1360 } 1361 else if (action == FLUSH_FIELD_ACTION) 1362 { 1363 _flush(((Class) arg1), arg2); 1364 } 1365 else if (action == GET_CLASS_LOADER_ACTION) 1366 { 1367 return ((Class) arg1).getClassLoader(); 1368 } 1369 1370 return null; 1371 } 1372 } 1373 }