1 17 18 package org.apache.geronimo.gbean.runtime; 19 20 import java.io.PrintWriter ; 21 import java.io.StringWriter ; 22 import java.lang.reflect.Constructor ; 23 import java.lang.reflect.InvocationTargetException ; 24 import java.util.Collection ; 25 import java.util.Collections ; 26 import java.util.HashMap ; 27 import java.util.HashSet ; 28 import java.util.Iterator ; 29 import java.util.LinkedHashSet ; 30 import java.util.List ; 31 import java.util.Map ; 32 import java.util.Set ; 33 import java.util.Arrays ; 34 35 import javax.management.ObjectName ; 36 37 import org.apache.commons.logging.Log; 38 import org.apache.commons.logging.LogFactory; 39 import org.apache.geronimo.gbean.AbstractName; 40 import org.apache.geronimo.gbean.AbstractNameQuery; 41 import org.apache.geronimo.gbean.GAttributeInfo; 42 import org.apache.geronimo.gbean.GBeanData; 43 import org.apache.geronimo.gbean.GBeanInfo; 44 import org.apache.geronimo.gbean.GBeanLifecycle; 45 import org.apache.geronimo.gbean.GConstructorInfo; 46 import org.apache.geronimo.gbean.GOperationInfo; 47 import org.apache.geronimo.gbean.GOperationSignature; 48 import org.apache.geronimo.gbean.GReferenceInfo; 49 import org.apache.geronimo.gbean.InvalidConfigurationException; 50 import org.apache.geronimo.gbean.ReferencePatterns; 51 import org.apache.geronimo.kernel.DependencyManager; 52 import org.apache.geronimo.kernel.GBeanNotFoundException; 53 import org.apache.geronimo.kernel.Kernel; 54 import org.apache.geronimo.kernel.NoSuchAttributeException; 55 import org.apache.geronimo.kernel.NoSuchOperationException; 56 import org.apache.geronimo.kernel.repository.Artifact; 57 import org.apache.geronimo.kernel.config.ManageableAttributeStore; 58 import org.apache.geronimo.kernel.management.State; 59 import org.apache.geronimo.kernel.management.StateManageable; 60 61 66 public final class GBeanInstance implements StateManageable { 67 private static final Log log = LogFactory.getLog(GBeanInstance.class); 68 69 private static final int DESTROYED = 0; 70 private static final int CREATING = 1; 71 private static final int RUNNING = 2; 72 private static final int DESTROYING = 3; 73 74 77 public static final String RAW_INVOKER = "$$RAW_INVOKER$$"; 78 79 82 private final Kernel kernel; 83 84 88 private ManageableAttributeStore manageableStore; 89 90 93 private final AbstractName abstractName; 94 95 98 private final GBeanInstanceState gbeanInstanceState; 99 100 103 private final Constructor constructor; 104 105 108 private final RawInvoker rawInvoker; 109 110 113 private final LifecycleBroadcaster lifecycleBroadcaster; 114 115 118 private final String [] interfaces; 119 120 123 private final GBeanAttribute[] attributes; 124 125 128 private final Map attributeIndex = new HashMap (); 129 130 133 private final GBeanReference[] references; 134 135 138 private final Map referenceIndex = new HashMap (); 139 140 143 private final GBeanDependency[] dependencies; 144 145 148 private final GBeanOperation[] operations; 149 150 153 private final Map operationIndex = new HashMap (); 154 155 158 private final ClassLoader classLoader; 159 160 163 private final GBeanInfo gbeanInfo; 164 165 168 private final String name; 169 170 173 private final Class type; 174 175 178 private boolean dead = false; 179 180 183 private int instanceState = DESTROYED; 184 185 188 private Object target; 189 190 193 private long startTime; 194 195 200 private boolean shouldFail = false; 201 202 205 private InstanceRegistry instanceRegistry; 206 207 private String stateReason; 208 209 218 public GBeanInstance(GBeanData gbeanData, Kernel kernel, DependencyManager dependencyManager, LifecycleBroadcaster lifecycleBroadcaster, ClassLoader classLoader) throws InvalidConfigurationException { 219 this.abstractName = gbeanData.getAbstractName(); 220 this.kernel = kernel; 221 this.lifecycleBroadcaster = lifecycleBroadcaster; 222 this.gbeanInstanceState = new GBeanInstanceState(abstractName, kernel, dependencyManager, this, lifecycleBroadcaster); 223 this.classLoader = classLoader; 224 225 GBeanInfo gbeanInfo = gbeanData.getGBeanInfo(); 226 try { 227 type = classLoader.loadClass(gbeanInfo.getClassName()); 228 } catch (ClassNotFoundException e) { 229 throw new InvalidConfigurationException("Could not load GBeanInfo class from classloader: " + classLoader + 230 " className=" + gbeanInfo.getClassName()); 231 } 232 233 name = gbeanInfo.getName(); 234 235 Set constructorArgs = new HashSet (gbeanInfo.getConstructor().getAttributeNames()); 237 238 interfaces = (String []) gbeanInfo.getInterfaces().toArray(new String [0]); 240 241 Map attributesMap = new HashMap (); 243 for (Iterator iterator = gbeanInfo.getAttributes().iterator(); iterator.hasNext();) { 244 GAttributeInfo attributeInfo = (GAttributeInfo) iterator.next(); 245 attributesMap.put(attributeInfo.getName(), new GBeanAttribute(this, attributeInfo, constructorArgs.contains(attributeInfo.getName()))); 246 } 247 addManagedObjectAttributes(attributesMap); 248 attributes = (GBeanAttribute[]) attributesMap.values().toArray(new GBeanAttribute[attributesMap.size()]); 249 for (int i = 0; i < attributes.length; i++) { 250 attributeIndex.put(attributes[i].getName(), new Integer (i)); 251 } 252 253 Set referencesSet = new HashSet (); 255 Set dependencySet = new HashSet (); 256 Map dataReferences = gbeanData.getReferences(); 258 for (Iterator iterator = gbeanInfo.getReferences().iterator(); iterator.hasNext();) { 259 GReferenceInfo referenceInfo = (GReferenceInfo) iterator.next(); 260 String referenceName = referenceInfo.getName(); 261 ReferencePatterns referencePatterns = (ReferencePatterns) dataReferences.remove(referenceName); 262 if (referenceInfo.getProxyType().equals(Collection .class.getName())) { 263 referencesSet.add(new GBeanCollectionReference(this, referenceInfo, kernel, referencePatterns)); 264 265 } else { 266 referencesSet.add(new GBeanSingleReference(this, referenceInfo, kernel, referencePatterns)); 267 if (referencePatterns != null) { 268 dependencySet.add(new GBeanDependency(this, referencePatterns.getAbstractName(), kernel)); 269 } 270 } 271 } 272 if (!dataReferences.isEmpty()) { 273 throw new IllegalStateException ("Attempting to set unknown references: " + dataReferences.keySet()); 274 } 275 276 references = (GBeanReference[]) referencesSet.toArray(new GBeanReference[referencesSet.size()]); 277 for (int i = 0; i < references.length; i++) { 278 referenceIndex.put(references[i].getName(), new Integer (i)); 279 } 280 281 for (Iterator iterator = gbeanData.getDependencies().iterator(); iterator.hasNext();) { 283 AbstractName dependencyName = ((ReferencePatterns) iterator.next()).getAbstractName(); 284 dependencySet.add(new GBeanDependency(this, dependencyName, kernel)); 285 } 286 287 dependencies = (GBeanDependency[]) dependencySet.toArray(new GBeanDependency[dependencySet.size()]); 288 289 291 Map operationsMap = new HashMap (); 293 for (Iterator iterator = gbeanInfo.getOperations().iterator(); iterator.hasNext();) { 294 GOperationInfo operationInfo = (GOperationInfo) iterator.next(); 295 GOperationSignature signature = new GOperationSignature(operationInfo.getName(), operationInfo.getParameterList()); 296 if (!operationsMap.containsKey(signature)) { 298 GBeanOperation operation = new GBeanOperation(this, operationInfo); 299 operationsMap.put(signature, operation); 300 } 301 } 302 operations = new GBeanOperation[operationsMap.size()]; 303 int opCounter = 0; 304 for (Iterator iterator = operationsMap.entrySet().iterator(); iterator.hasNext();) { 305 Map.Entry entry = (Map.Entry ) iterator.next(); 306 operations[opCounter] = (GBeanOperation) entry.getValue(); 307 operationIndex.put(entry.getKey(), new Integer (opCounter)); 308 opCounter++; 309 } 310 311 List arguments = gbeanInfo.getConstructor().getAttributeNames(); 313 Class [] parameterTypes = new Class [arguments.size()]; 314 for (int i = 0; i < parameterTypes.length; i++) { 315 String argumentName = (String ) arguments.get(i); 316 if (referenceIndex.containsKey(argumentName)) { 317 Integer index = (Integer ) referenceIndex.get(argumentName); 318 GBeanReference reference = references[index.intValue()]; 319 parameterTypes[i] = reference.getProxyType(); 320 } else if (attributeIndex.containsKey(argumentName)) { 321 Integer index = (Integer ) attributeIndex.get(argumentName); 322 GBeanAttribute attribute = attributes[index.intValue()]; 323 parameterTypes[i] = attribute.getType(); 324 } 325 } 326 try { 327 constructor = type.getConstructor(parameterTypes); 328 } catch (NoSuchMethodException e) { 329 StringBuffer buf = new StringBuffer ("Could not find a valid constructor for GBean: ").append(gbeanInfo.getName()).append("\n"); 330 buf.append("ParameterTypes: ").append(Arrays.asList(parameterTypes)).append("\n"); 331 Constructor [] constructors = type.getConstructors(); 332 for (int i = 0; i < constructors.length; i++) { 333 Constructor testConstructor = constructors[i]; 334 buf.append("constructor types: ").append(Arrays.asList(testConstructor.getParameterTypes())).append("\n"); 335 if (testConstructor.getParameterTypes().length == parameterTypes.length) { 336 Class [] testParameterTypes = testConstructor.getParameterTypes(); 337 for (int k = 0; k < testParameterTypes.length; k++) { 338 Class testParameterType = testParameterTypes[k]; 339 if (parameterTypes[k].getName().equals(testParameterType.getName())) { 340 if (parameterTypes[k].getClassLoader() != testParameterType.getClassLoader()) { 341 buf.append("different classloaders in position: ").append(k).append(" class name: ").append(testParameterType.getName()).append("\n"); 342 buf.append("parameter type classloader: ").append(parameterTypes[k].getClassLoader()).append("\n"); 343 buf.append("constructor type classloader: ").append(testParameterType.getClassLoader()).append("\n"); 344 } 345 } else { 346 buf.append("different type in position: ").append(k).append("\n"); 347 } 348 } 349 } 350 } 351 throw new InvalidConfigurationException(buf.toString()); 352 } 353 354 this.gbeanInfo = rebuildGBeanInfo(gbeanInfo.getConstructor(), gbeanInfo.getJ2eeType()); 357 358 rawInvoker = new RawInvoker(this); 360 361 try { 363 Map dataAttributes = gbeanData.getAttributes(); 365 for (Iterator iterator = dataAttributes.entrySet().iterator(); iterator.hasNext();) { 366 Map.Entry entry = (Map.Entry ) iterator.next(); 367 String attributeName = (String ) entry.getKey(); 368 Object attributeValue = entry.getValue(); 369 if (entry.getValue() != null) { 370 setAttribute(attributeName, attributeValue, false); 371 } 372 } 373 374 } catch (Exception e) { 375 throw new InvalidConfigurationException("Could not inject configuration data into the GBean " + abstractName, e); 376 } 377 378 for (int i = 0; i < dependencies.length; i++) { 379 dependencies[i].online(); 380 } 381 for (int i = 0; i < references.length; i++) { 382 references[i].online(); 383 } 384 } 385 386 public void die() throws GBeanNotFoundException { 387 synchronized (this) { 388 if (dead) { 389 throw new GBeanNotFoundException(abstractName); 391 } 392 dead = true; 393 } 394 395 gbeanInstanceState.fail(); 397 398 for (int i = 0; i < references.length; i++) { 399 references[i].offline(); 400 } 401 for (int i = 0; i < dependencies.length; i++) { 402 dependencies[i].offline(); 403 } 404 405 lifecycleBroadcaster.fireUnloadedEvent(); 407 408 manageableStore = null; 409 } 410 411 public synchronized void setInstanceRegistry(InstanceRegistry instanceRegistry) { 412 this.instanceRegistry = instanceRegistry; 413 } 414 415 420 public String getName() { 421 return name; 422 } 423 424 430 public ClassLoader getClassLoader() { 431 return classLoader; 432 } 433 434 439 public synchronized boolean isDead() { 440 return dead; 441 } 442 443 447 public String getStateReason() { 448 return stateReason; 449 } 450 451 456 public Class getType() { 457 return type; 458 } 459 460 public synchronized Object getTarget() { 461 return target; 462 } 463 464 public final String getObjectName() { 465 return abstractName.getObjectName().getCanonicalName(); 466 } 467 468 public final ObjectName getObjectNameObject() { 469 return abstractName.getObjectName(); 470 } 471 472 public final AbstractName getAbstractName() { 473 return abstractName; 474 } 475 476 public synchronized final long getStartTime() { 477 return startTime; 478 } 479 480 public int getState() { 481 return gbeanInstanceState.getState(); 482 } 483 484 public final State getStateInstance() { 485 return gbeanInstanceState.getStateInstance(); 486 } 487 488 494 public Map getAttributeIndex() { 495 return Collections.unmodifiableMap(new HashMap (attributeIndex)); 496 } 497 498 504 public Map getOperationIndex() { 505 return Collections.unmodifiableMap(new HashMap (operationIndex)); 506 } 507 508 513 public GBeanInfo getGBeanInfo() { 514 return gbeanInfo; 515 } 516 517 523 public final void start() { 524 synchronized (this) { 525 if (dead) { 526 throw new IllegalStateException ("A dead GBean can not be started: abstractName=" + abstractName); 527 } 528 } 529 gbeanInstanceState.start(); 530 } 531 532 537 public final void startRecursive() { 538 synchronized (this) { 539 if (dead) { 540 throw new IllegalStateException ("A dead GBean can not be started: abstractName=" + abstractName); 541 } 542 } 543 gbeanInstanceState.startRecursive(); 544 } 545 546 550 public final void stop() { 551 gbeanInstanceState.stop(); 552 } 553 554 558 final void referenceFailed() { 559 gbeanInstanceState.fail(); 560 } 561 562 567 public GBeanData getGBeanData() { 568 GBeanData gbeanData = new GBeanData(abstractName, gbeanInfo); 569 570 int state; 572 Object instance; 573 synchronized (this) { 574 state = instanceState; 575 instance = target; 576 } 577 578 for (int i = 0; i < attributes.length; i++) { 580 GBeanAttribute attribute = attributes[i]; 581 if (attribute.isPersistent()) { 582 String name = attribute.getName(); 583 Object value; 584 if ((state != DESTROYED || attribute.isFramework()) && attribute.isReadable()) { 585 try { 586 value = attribute.getValue(instance); 587 } catch (Throwable throwable) { 588 value = attribute.getPersistentValue(); 589 log.debug("Could not get the current value of persistent attribute. The persistent " + 590 "attribute will not reflect the current state attribute. " + attribute.getDescription(), throwable); 591 } 592 } else { 593 value = attribute.getPersistentValue(); 594 } 595 gbeanData.setAttribute(name, value); 596 } 597 } 598 599 for (int i = 0; i < references.length; i++) { 601 GBeanReference reference = references[i]; 602 String name = reference.getName(); 603 if(reference instanceof GBeanSingleReference) { 604 AbstractName abstractName = ((GBeanSingleReference) reference).getTargetName(); 605 if(abstractName != null) { 606 gbeanData.setReferencePattern(name, abstractName); 607 } 608 } else if(reference instanceof GBeanCollectionReference) { 609 Set patterns = ((GBeanCollectionReference) reference).getPatterns(); 610 if(patterns != null) { 611 gbeanData.setReferencePatterns(name, patterns); 612 } 613 } else { 614 throw new IllegalStateException ("Unrecognized GBeanReference '"+reference.getClass().getName()+"'"); 615 } 616 } 617 return gbeanData; 619 } 620 621 630 public Object getAttribute(int index) throws Exception { 631 GBeanAttribute attribute = attributes[index]; 632 633 int state; 635 Object instance; 636 synchronized (this) { 637 state = instanceState; 638 instance = target; 639 } 640 641 if (state != DESTROYED || attribute.isFramework()) { 642 return attribute.getValue(instance); 643 } else { 644 if (attribute.isPersistent()) { 645 return attribute.getPersistentValue(); 646 } else { 647 throw new IllegalStateException ("Cannot retrieve the value for non-persistent attribute \"" + attribute.getName() + "\" when GBeanInstance is DESTROYED"); 648 } 649 } 650 } 651 652 661 public Object getAttribute(String attributeName) throws NoSuchAttributeException, Exception { 662 GBeanAttribute attribute; 663 try { 664 attribute = getAttributeByName(attributeName); 665 } catch (NoSuchAttributeException e) { 666 if (attributeName.equals(RAW_INVOKER)) { 667 return rawInvoker; 668 } 669 throw e; 670 } 671 672 int state; 674 Object instance; 675 synchronized (this) { 676 state = instanceState; 677 instance = target; 678 } 679 680 if (state != DESTROYED || attribute.isFramework()) { 681 return attribute.getValue(instance); 682 } else { 683 if (attribute.isPersistent()) { 684 return attribute.getPersistentValue(); 685 } else { 686 throw new IllegalStateException ("Cannot retrieve the value for non-persistent attribute " + attributeName + " when gbean has been destroyed: " + abstractName); 687 } 688 } 689 } 690 691 700 public void setAttribute(int index, Object value) throws Exception , IndexOutOfBoundsException { 701 setAttribute(index, value, true); 702 } 703 704 private void setAttribute(int index, Object value, boolean manage) throws Exception , IndexOutOfBoundsException { 705 GBeanAttribute attribute = attributes[index]; 706 707 int state; 709 Object instance; 710 synchronized (this) { 711 state = instanceState; 712 instance = target; 713 } 714 715 if (state != DESTROYED || attribute.isFramework()) { 716 attribute.setValue(instance, value); 717 } else { 718 attribute.setPersistentValue(value); 719 } 720 if (manage && attribute.isManageable()) { 721 updateManageableAttribute(attribute, value); 722 } 723 } 724 725 734 public void setAttribute(String attributeName, Object value) throws Exception , NoSuchAttributeException { 735 setAttribute(attributeName, value, true); 736 } 737 738 public void setAttribute(String attributeName, Object value, boolean manage) throws Exception , NoSuchAttributeException { 739 GBeanAttribute attribute = getAttributeByName(attributeName); 740 741 int state; 743 Object instance; 744 synchronized (this) { 745 state = instanceState; 746 instance = target; 747 } 748 749 if (state != DESTROYED || attribute.isFramework()) { 750 attribute.setValue(instance, value); 751 } else { 752 attribute.setPersistentValue(value); 753 } 754 if (manage && attribute.isManageable()) { 755 updateManageableAttribute(attribute, value); 756 } 757 } 758 759 private void updateManageableAttribute(GBeanAttribute attribute, Object value) { 760 if (manageableStore == null) { 761 manageableStore = getManageableAttributeStore(); 762 if (manageableStore == null) { 763 return; 764 } 765 } 766 Artifact configName = abstractName.getArtifact(); 767 if (configName != null) { 768 manageableStore.setValue(configName, abstractName, attribute.getAttributeInfo(), value); 769 } else { 770 log.error("Unable to identify Configuration for GBean " + abstractName + ". Manageable attribute " + attribute.getName() + " was not updated in persistent store."); 771 } 772 } 773 774 private ManageableAttributeStore getManageableAttributeStore() { 775 Set set = kernel.listGBeans(new AbstractNameQuery(ManageableAttributeStore.class.getName())); 776 for (Iterator iterator = set.iterator(); iterator.hasNext();) { 777 AbstractName abstractName1 = (AbstractName) iterator.next(); 778 try { 779 return (ManageableAttributeStore) kernel.getGBean(abstractName1); 780 } catch (GBeanNotFoundException e) { 781 } 783 } 784 return null; 785 } 786 787 private GBeanAttribute getAttributeByName(String name) throws NoSuchAttributeException { 788 Integer index = (Integer ) attributeIndex.get(name); 789 if (index == null) { 790 throw new NoSuchAttributeException("Unknown attribute \"" + name + "\" in gbean " + abstractName); 791 } 792 return attributes[index.intValue()]; 793 } 794 795 806 public Object invoke(int index, Object [] arguments) throws Exception { 807 GBeanOperation operation = operations[index]; 808 809 int state; 811 Object instance; 812 synchronized (this) { 813 state = instanceState; 814 instance = target; 815 } 816 817 if (state == DESTROYED && !operation.isFramework()) { 818 throw new IllegalStateException ("Operations can only be invoke while the GBean instance is running: " + abstractName); 819 } 820 return operation.invoke(instance, arguments); 821 } 822 823 836 public Object invoke(String operationName, Object [] arguments, String [] types) throws Exception , NoSuchOperationException { 837 GOperationSignature signature = new GOperationSignature(operationName, types); 838 Integer index = (Integer ) operationIndex.get(signature); 839 if (index == null) { 840 throw new NoSuchOperationException("Unknown operation " + signature); 841 } 842 GBeanOperation operation = operations[index.intValue()]; 843 844 int state; 846 Object instance; 847 synchronized (this) { 848 state = instanceState; 849 instance = target; 850 } 851 852 if (state == DESTROYED && !operation.isFramework()) { 853 throw new IllegalStateException ("Operations can only be invoke while the GBean is running: " + abstractName); 854 } 855 return operation.invoke(instance, arguments); 856 } 857 858 private GBeanReference getReferenceByName(String name) { 859 Integer index = (Integer ) referenceIndex.get(name); 860 if (index == null) { 861 throw new IllegalArgumentException ("Unknown reference " + name); 862 } 863 return references[index.intValue()]; 864 } 865 866 boolean createInstance() throws Exception { 867 synchronized (this) { 868 if (instanceState == CREATING || instanceState == RUNNING) { 870 return false; 872 } else if (instanceState == DESTROYING) { 873 stateReason = "an internal error has occurred. An was made to start an instance that was still stopping which is an illegal state transition."; 876 throw new IllegalStateException ("A stopping instance can not be started until fully stopped"); 877 } 878 assert instanceState == DESTROYED; 879 880 stateReason = null; 881 882 LinkedHashSet unstarted = new LinkedHashSet (); 884 for (int i = 0; i < dependencies.length; i++) { 885 if (!dependencies[i].start()) { 886 unstarted.add(dependencies[i].getTargetName()); 887 } 888 } 889 for (int i = 0; i < references.length; i++) { 890 if (!references[i].start()) { 891 if (references[i] instanceof GBeanSingleReference) { 892 GBeanSingleReference reference = (GBeanSingleReference) references[i]; 893 unstarted.add(reference.getTargetName()); 894 } 895 } 896 } 897 if (!unstarted.isEmpty()) { 898 if (unstarted.size() == 1) { 899 stateReason = unstarted.iterator().next() + " did not start."; 900 } else { 901 stateReason = "the following dependent services did not start: " + unstarted; 902 } 903 return false; 904 } 905 906 instanceState = CREATING; 908 startTime = System.currentTimeMillis(); 909 } 910 911 ClassLoader oldCL = Thread.currentThread().getContextClassLoader(); 912 Thread.currentThread().setContextClassLoader(classLoader); 913 Object instance = null; 914 try { 915 GConstructorInfo constructorInfo = gbeanInfo.getConstructor(); 916 Class [] parameterTypes = constructor.getParameterTypes(); 917 918 Object [] parameters = new Object [parameterTypes.length]; 920 Iterator names = constructorInfo.getAttributeNames().iterator(); 921 for (int i = 0; i < parameters.length; i++) { 922 String name = (String ) names.next(); 923 if (referenceIndex.containsKey(name)) { 924 parameters[i] = getReferenceByName(name).getProxy(); 925 } else if (attributeIndex.containsKey(name)) { 926 GBeanAttribute attribute = getAttributeByName(name); 927 parameters[i] = attribute.getPersistentValue(); 928 } else { 929 stateReason = "the service constructor definition contained the name '" + name + "' which is not a known attribute or reference of the service."; 930 throw new InvalidConfigurationException("Unknown attribute or reference name in constructor: referenceName=" + name + ", gbean=" + abstractName); 931 } 932 } 933 934 try { 936 instance = constructor.newInstance(parameters); 937 } catch (InvocationTargetException e) { 938 Throwable targetException = e.getTargetException(); 939 if (targetException instanceof Exception ) { 940 throw (Exception ) targetException; 941 } else if (targetException instanceof Error ) { 942 throw (Error ) targetException; 943 } 944 stateReason = "the service constructor threw an exception. \n" + printException(e); 945 throw e; 946 } catch (IllegalArgumentException e) { 947 stateReason = "the service constructor threw an exception due to a parameter type mismatch. \n" + printException(e); 948 log.warn("Constructor mismatch for " + abstractName, e); 949 throw e; 950 } 951 952 synchronized (this) { 956 target = instance; 957 } 958 959 for (int i = 0; i < attributes.length; i++) { 961 checkIfShouldFail(); 962 try { 963 attributes[i].inject(instance); 964 } catch (Exception e) { 965 stateReason = "the setter for attribute '" + attributes[i].getName() + "' threw an exception. \n" + printException(e); 966 throw e; 967 } 968 } 969 970 for (int i = 0; i < references.length; i++) { 972 checkIfShouldFail(); 973 try { 974 references[i].inject(instance); 975 } catch (Exception e) { 976 stateReason = "the setter for reference '" + references[i].getName() + "' threw an exception. \n" + printException(e); 977 throw e; 978 } 979 } 980 981 if (instance instanceof GBeanLifecycle) { 982 checkIfShouldFail(); 983 try { 984 ((GBeanLifecycle) instance).doStart(); 985 } catch (Exception e) { 986 stateReason = "the doStart method threw an exception. \n" + printException(e); 987 throw e; 988 } 989 } 990 991 992 synchronized (this) { 994 checkIfShouldFail(); 995 if (instanceRegistry != null) { 996 instanceRegistry.instanceCreated(instance, this); 997 } 998 instanceState = RUNNING; 999 this.notifyAll(); 1000 } 1001 1002 1003 stateReason = null; 1004 return true; 1005 } catch (Throwable t) { 1006 synchronized (this) { 1008 instanceState = DESTROYING; 1009 } 1010 1011 if (instance instanceof GBeanLifecycle) { 1012 try { 1013 ((GBeanLifecycle) instance).doFail(); 1014 } catch (Throwable ignored) { 1015 log.error("Problem in doFail of " + abstractName, ignored); 1016 } 1017 } 1018 1019 synchronized (this) { 1021 for (int i = 0; i < references.length; i++) { 1023 references[i].stop(); 1024 } 1025 for (int i = 0; i < dependencies.length; i++) { 1026 dependencies[i].stop(); 1027 } 1028 1029 target = null; 1030 instanceState = DESTROYED; 1031 startTime = 0; 1032 this.notifyAll(); 1033 } 1034 1035 if (t instanceof Exception ) { 1036 throw (Exception ) t; 1037 } else if (t instanceof Error ) { 1038 throw (Error ) t; 1039 } else { 1040 throw new Error (t); 1041 } 1042 } finally { 1043 Thread.currentThread().setContextClassLoader(oldCL); 1044 } 1045 } 1046 1047 private String printException(Throwable t) { 1048 StringWriter stringWriter = new StringWriter (); 1049 PrintWriter printWriter = new PrintWriter (stringWriter); 1050 t.printStackTrace(printWriter); 1051 printWriter.flush(); 1052 return stringWriter.toString(); 1053 } 1054 1055 private synchronized void checkIfShouldFail() throws Exception { 1056 if (shouldFail) { 1057 shouldFail = false; 1058 throw new Exception ("A reference has failed so construction can not complete"); 1059 } 1060 } 1061 1062 boolean destroyInstance(boolean stop) throws Exception { 1063 Object instance; 1064 synchronized (this) { 1065 if (!stop && instanceState == CREATING) { 1066 shouldFail = true; 1068 return false; 1069 } 1070 1071 while (instanceState == CREATING) { 1074 try { 1076 this.wait(); 1077 } catch (InterruptedException e) { 1078 Thread.interrupted(); 1080 throw e; 1082 } 1083 } 1084 1085 if (instanceState == DESTROYING || instanceState == DESTROYED) { 1086 return false; 1088 } 1089 assert instanceState == RUNNING; 1090 stateReason = null; 1091 1092 instanceState = DESTROYING; 1094 instance = target; 1095 } 1096 1097 Exception problem = null; 1101 if (stop && instance != null) { 1102 try { 1103 Map data = new HashMap (); 1105 for (int i = 0; i < attributes.length; i++) { 1106 GBeanAttribute attribute = attributes[i]; 1107 if (attribute.isPersistent() && attribute.isReadable()) { 1108 Object value; 1110 try { 1111 value = attribute.getValue(instance); 1112 } catch (Throwable e) { 1113 throw new Exception ("Problem while updaing the persistent value of attibute: " + 1116 "Attribute Name: " + attribute.getName() + ", " + 1117 "Type: " + attribute.getType() + ", " + 1118 "GBeanInstance: " + getName(), e); 1119 } 1120 data.put(attribute, value); 1121 } 1122 } 1123 for (int i = 0; i < attributes.length; i++) { 1125 GBeanAttribute attribute = attributes[i]; 1126 if (attribute.isPersistent() && attribute.isReadable()) { 1127 Object value = data.get(attribute); 1129 attribute.setPersistentValue(value); 1130 } 1131 } 1132 } catch (Exception e) { 1133 stop = false; 1135 problem = e; 1136 } 1137 } 1138 1139 ClassLoader oldCL = Thread.currentThread().getContextClassLoader(); 1141 Thread.currentThread().setContextClassLoader(classLoader); 1142 try { 1143 if (instance instanceof GBeanLifecycle) { 1144 if (stop) { 1145 try { 1146 ((GBeanLifecycle) instance).doStop(); 1147 } catch (Throwable ignored) { 1148 log.error("Problem in doStop of " + abstractName, ignored); 1149 } 1150 } else { 1151 try { 1152 ((GBeanLifecycle) instance).doFail(); 1153 } catch (Throwable ignored) { 1154 log.error("Problem in doFail of " + abstractName, ignored); 1155 } 1156 } 1157 } 1158 } finally { 1159 Thread.currentThread().setContextClassLoader(oldCL); 1160 } 1161 1162 synchronized (this) { 1164 for (int i = 0; i < references.length; i++) { 1166 references[i].stop(); 1167 } 1168 for (int i = 0; i < dependencies.length; i++) { 1169 dependencies[i].stop(); 1170 } 1171 1172 target = null; 1173 instanceState = DESTROYED; 1174 if (instanceRegistry != null) { 1175 instanceRegistry.instanceDestroyed(instance); 1176 } 1177 startTime = 0; 1178 } 1179 1180 if (problem != null) { 1181 throw problem; 1182 } 1183 return true; 1184 } 1185 1186 private void addManagedObjectAttributes(Map attributesMap) { 1187 attributesMap.put("abstractName", 1191 GBeanAttribute.createSpecialAttribute((GBeanAttribute) attributesMap.get("abstractName"), 1192 this, 1193 "abstractName", 1194 AbstractName.class, 1195 getAbstractName())); 1196 1197 attributesMap.put("objectName", 1198 GBeanAttribute.createSpecialAttribute((GBeanAttribute) attributesMap.get("objectName"), 1199 this, 1200 "objectName", 1201 String .class, 1202 getObjectName())); 1203 1204 attributesMap.put("classLoader", 1205 GBeanAttribute.createSpecialAttribute((GBeanAttribute) attributesMap.get("classLoader"), 1206 this, 1207 "classLoader", 1208 ClassLoader .class, 1209 classLoader)); 1210 1211 attributesMap.put("kernel", 1212 GBeanAttribute.createSpecialAttribute((GBeanAttribute) attributesMap.get("kernel"), 1213 this, 1214 "kernel", 1215 Kernel.class, 1216 kernel)); 1217 1218 } 1219 1220 private GBeanInfo rebuildGBeanInfo(GConstructorInfo constructor, String j2eeType) { 1221 Set attributeInfos = new HashSet (); 1222 for (int i = 0; i < attributes.length; i++) { 1223 GBeanAttribute attribute = attributes[i]; 1224 attributeInfos.add(attribute.getAttributeInfo()); 1225 } 1226 Set operationInfos = new HashSet (); 1227 for (int i = 0; i < operations.length; i++) { 1228 operationInfos.add(operations[i].getOperationInfo()); 1229 } 1230 1231 Set referenceInfos = new HashSet (); 1232 for (int i = 0; i < references.length; i++) { 1233 referenceInfos.add(references[i].getReferenceInfo()); 1234 } 1235 1236 Set interfaceInfos = new HashSet (); 1237 for (int i = 0; i < interfaces.length; i++) { 1238 interfaceInfos.add(interfaces[i]); 1239 } 1240 1241 return new GBeanInfo(name, 1242 type.getName(), 1243 j2eeType, 1244 attributeInfos, 1245 constructor, 1246 operationInfos, 1247 referenceInfos, 1248 interfaceInfos); 1249 } 1250 1251 public boolean equals(Object obj) { 1252 if (obj == this) return true; 1253 if (!(obj instanceof GBeanInstance)) return false; 1254 return abstractName.equals(((GBeanInstance) obj).abstractName); 1255 } 1256 1257 public int hashCode() { 1258 return abstractName.hashCode(); 1259 } 1260 1261 public String toString() { 1262 return abstractName.toString(); 1263 } 1264} 1265 | Popular Tags |