001/* 002 * Copyright 2002-2016 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.beans.factory; 018 019import java.io.PrintStream; 020import java.io.PrintWriter; 021import java.util.LinkedList; 022import java.util.List; 023 024import org.springframework.beans.FatalBeanException; 025import org.springframework.core.NestedRuntimeException; 026 027/** 028 * Exception thrown when a BeanFactory encounters an error when 029 * attempting to create a bean from a bean definition. 030 * 031 * @author Juergen Hoeller 032 */ 033@SuppressWarnings("serial") 034public class BeanCreationException extends FatalBeanException { 035 036 private String beanName; 037 038 private String resourceDescription; 039 040 private List<Throwable> relatedCauses; 041 042 043 /** 044 * Create a new BeanCreationException. 045 * @param msg the detail message 046 */ 047 public BeanCreationException(String msg) { 048 super(msg); 049 } 050 051 /** 052 * Create a new BeanCreationException. 053 * @param msg the detail message 054 * @param cause the root cause 055 */ 056 public BeanCreationException(String msg, Throwable cause) { 057 super(msg, cause); 058 } 059 060 /** 061 * Create a new BeanCreationException. 062 * @param beanName the name of the bean requested 063 * @param msg the detail message 064 */ 065 public BeanCreationException(String beanName, String msg) { 066 super("Error creating bean" + (beanName != null ? " with name '" + beanName + "'" : "") + ": " + msg); 067 this.beanName = beanName; 068 } 069 070 /** 071 * Create a new BeanCreationException. 072 * @param beanName the name of the bean requested 073 * @param msg the detail message 074 * @param cause the root cause 075 */ 076 public BeanCreationException(String beanName, String msg, Throwable cause) { 077 this(beanName, msg); 078 initCause(cause); 079 } 080 081 /** 082 * Create a new BeanCreationException. 083 * @param resourceDescription description of the resource 084 * that the bean definition came from 085 * @param beanName the name of the bean requested 086 * @param msg the detail message 087 */ 088 public BeanCreationException(String resourceDescription, String beanName, String msg) { 089 super("Error creating bean" + (beanName != null ? " with name '" + beanName + "'" : "") + 090 (resourceDescription != null ? " defined in " + resourceDescription : "") + ": " + msg); 091 this.resourceDescription = resourceDescription; 092 this.beanName = beanName; 093 } 094 095 /** 096 * Create a new BeanCreationException. 097 * @param resourceDescription description of the resource 098 * that the bean definition came from 099 * @param beanName the name of the bean requested 100 * @param msg the detail message 101 * @param cause the root cause 102 */ 103 public BeanCreationException(String resourceDescription, String beanName, String msg, Throwable cause) { 104 this(resourceDescription, beanName, msg); 105 initCause(cause); 106 } 107 108 109 /** 110 * Return the name of the bean requested, if any. 111 */ 112 public String getBeanName() { 113 return this.beanName; 114 } 115 116 /** 117 * Return the description of the resource that the bean 118 * definition came from, if any. 119 */ 120 public String getResourceDescription() { 121 return this.resourceDescription; 122 } 123 124 /** 125 * Add a related cause to this bean creation exception, 126 * not being a direct cause of the failure but having occurred 127 * earlier in the creation of the same bean instance. 128 * @param ex the related cause to add 129 */ 130 public void addRelatedCause(Throwable ex) { 131 if (this.relatedCauses == null) { 132 this.relatedCauses = new LinkedList<Throwable>(); 133 } 134 this.relatedCauses.add(ex); 135 } 136 137 /** 138 * Return the related causes, if any. 139 * @return the array of related causes, or {@code null} if none 140 */ 141 public Throwable[] getRelatedCauses() { 142 if (this.relatedCauses == null) { 143 return null; 144 } 145 return this.relatedCauses.toArray(new Throwable[this.relatedCauses.size()]); 146 } 147 148 149 @Override 150 public String toString() { 151 StringBuilder sb = new StringBuilder(super.toString()); 152 if (this.relatedCauses != null) { 153 for (Throwable relatedCause : this.relatedCauses) { 154 sb.append("\nRelated cause: "); 155 sb.append(relatedCause); 156 } 157 } 158 return sb.toString(); 159 } 160 161 @Override 162 public void printStackTrace(PrintStream ps) { 163 synchronized (ps) { 164 super.printStackTrace(ps); 165 if (this.relatedCauses != null) { 166 for (Throwable relatedCause : this.relatedCauses) { 167 ps.println("Related cause:"); 168 relatedCause.printStackTrace(ps); 169 } 170 } 171 } 172 } 173 174 @Override 175 public void printStackTrace(PrintWriter pw) { 176 synchronized (pw) { 177 super.printStackTrace(pw); 178 if (this.relatedCauses != null) { 179 for (Throwable relatedCause : this.relatedCauses) { 180 pw.println("Related cause:"); 181 relatedCause.printStackTrace(pw); 182 } 183 } 184 } 185 } 186 187 @Override 188 public boolean contains(Class<?> exClass) { 189 if (super.contains(exClass)) { 190 return true; 191 } 192 if (this.relatedCauses != null) { 193 for (Throwable relatedCause : this.relatedCauses) { 194 if (relatedCause instanceof NestedRuntimeException && 195 ((NestedRuntimeException) relatedCause).contains(exClass)) { 196 return true; 197 } 198 } 199 } 200 return false; 201 } 202 203}