VRaptor 3 - NoSuchBeanDefinitionException: No unique bean of type

5 respostas
yorgan

Tenho um projeto java com epenas dois arquivos, uma interface e uma classe.
Essa interface extende a interface br.com.caelum.vraptor.View para tratar alguns casos específicos na serialização de objetos JSON.

ExtJSJson.java

import br.com.caelum.vraptor.View;

public interface ExtJSJson extends View {
	
	public ExtJSJsonImpl from(Object object);
	
	public ExtJSJsonImpl success();
	
	public ExtJSJsonImpl success(boolean success);
	
	public ExtJSJsonImpl selected(Object value);
	
	public ExtJSJsonImpl exclude(String... names);
	
	public ExtJSJsonImpl include(String... fields);
	
	public ExtJSJsonImpl upload(String fileName);
	
	public ExtJSJsonImpl serialize();
	
}

E a implantação dela na classe ExtJSJsonImpl.java

@Component
public class ExtJSJsonImpl implements ExtJSJson {
private final Multimap<Class<?>, String> excludes = LinkedListMultimap.create();
	private final XStream xstream;
	private final HttpServletResponse response;
	private final String SUCCESS  = "{\"success\": ";
	private final String SELECTED = ",\n \"selected\": @value }";
	
	private Set<Class<?>> elementTypes;
	private Class<?> rootClass;
	
	private Object object;
	private String json;
	private boolean convertToJson = true;
	
	private boolean includeSuccess = false;
	private boolean successValue   = true;
	
	private boolean includeSelected = false;
	private Object  selectedValue;
	
	
	public ExtJSJsonImpl(HttpServletResponse response) {
		this.xstream  = new XStream(new JsonHierarchicalStreamDriver());
		this.response = response;
	}
	
	public ExtJSJsonImpl from(Object object) {
		response.setContentType("application/json; charset=ISO-8859-1");
		this.rootClass = object.getClass();
		this.object    = object;
		return this;
	}
	
	public ExtJSJsonImpl success() {
		return success(true);
	}
	
	public ExtJSJsonImpl success(boolean success) {
		includeSuccess = true;
		successValue   = success;
		return this;
	}
	
	public ExtJSJsonImpl selected(Object value) {
		if(value != null) {
			includeSelected = true;
			selectedValue = value;
		}
		return this;
	}
	
	public ExtJSJsonImpl exclude(String... names) {
		for (String name : names) {
			Set<Class<?>> parentTypes = getParentTypesFor(name);
			for (Class<?> type : parentTypes) {
				xstream.omitField(type, getNameFor(name));
			}
		}
		return this;
	}
	
	public ExtJSJsonImpl include(String... fields) {
		for (String field : fields) {
			try {
				Set<Class<?>> parentTypes = getParentTypesFor(field);
				String fieldName = getNameFor(field);
				for (Class<?> parentType : parentTypes) {
					Type genericType = new Mirror().on(parentType).reflect().field(fieldName).getGenericType();
					Class<?> fieldType = getActualType(genericType);

					if (!excludes.containsKey(fieldType)) {
						excludeNonPrimitiveFields(fieldType);
					}
					excludes.remove(parentType, fieldName);
				}
			} catch (NullPointerException e) {
				throw new IllegalArgumentException("Field path " + field + " doesn't exist");
			}
		}
		return this;
	}
	
	public ExtJSJsonImpl upload(String fileName) {
		response.setContentType("text/html");
		convertToJson = false;
		fileName = fileName != null ? fileName : "undefined";
		json = "{success:" + successValue + ", file:\"" + fileName + "\"}";
		return this;
	}
	
	public ExtJSJsonImpl serialize() {
		if(convertToJson) 
			this.json = objectToJSON();
		
		if(includeSelected) 
			includeSelected();
			
		if(includeSuccess)
			includeSuccess();
		
		try {
			response.getWriter().write(json);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return this;
	}
	
	private void excludeNonPrimitiveFields(Class<?> type) {
		for (Field field : new Mirror().on(type).reflectAll().fields()) {
			if (!isPrimitive(field.getType())) {
				excludes.put(type, field.getName());
			}
		}
	}

	private String objectToJSON() {
		xstream.setMode(XStream.NO_REFERENCES);
        xstream.alias("data", object.getClass());

        for(Class clazz : object.getClass().getInterfaces()) {
        	xstream.alias("data", clazz);
        }
        
        String json = xstream.toXML(object).trim();
        if(json.endsWith("}}")) {
        	json = json.substring(0, json.length() - 2) + " }\n}";
        }
        return json;
	}
	
	private String getNameFor(String name) {
		String[] path = name.split("\\.");
		return path[path.length-1];
	}
	
	private Set<Class<?>> getParentTypesFor(String name) {
		if (elementTypes == null) {
			Class<?> type = rootClass;
			return Collections.<Class<?>>singleton(getParentType(name, type));
		} else {
			Set<Class<?>> result = new HashSet<Class<?>>();
			for (Class<?> type : elementTypes) {
				result.add(getParentType(name, type));
			}
			return result;
		}
	}
	
	private Class<?> getParentType(String name, Class<?> type) {
		String[] path = name.split("\\.");
		for (int i = 0; i < path.length - 1; i++) {
			type = getActualType(new Mirror().on(type).reflect().field(path[i]).getGenericType());
		}
		return type;
	}
	
	private Class<?> getActualType(Type genericType) {
		if (genericType instanceof ParameterizedType) {
			ParameterizedType type = (ParameterizedType) genericType;
			if (isCollection(type)) {
				return (Class<?>) type.getActualTypeArguments()[0];
			}
		}
		return (Class<?>) genericType;
	}
	
	private boolean isCollection(Type type) {
		if (type instanceof ParameterizedType) {
			ParameterizedType ptype = (ParameterizedType) type;
			return Collection.class.isAssignableFrom((Class<?>) ptype.getRawType())
			  || Map.class.isAssignableFrom((Class<?>) ptype.getRawType());
		}
		return Collection.class.isAssignableFrom((Class<?>) type);
	}
	
	private void includeSuccess() {
		if(json != null && json.length() > 0 && json.startsWith("{") && json.endsWith("}")) {
			this.json = SUCCESS + successValue + ", \n " + this.json.substring(1); 
		}
	}
	
	private void includeSelected() {
		if(json != null && json.length() > 0 && json.startsWith("{") && json.endsWith("}")) {
			String v = null;
			if(isNumeric(selectedValue.getClass())) {
				v = selectedValue.toString();
			} else {
				v = "\"" + selectedValue.toString() + "\"";
			}
			this.json = this.json.substring(0, json.length() - 1) + SELECTED.replace("@value", v); 
		}
	}
	
	private boolean isPrimitive(Class<?> type) {
		return type.isPrimitive()
			|| type.isEnum()
			|| Number.class.isAssignableFrom(type)
			|| type.equals(String.class)
			|| Date.class.isAssignableFrom(type)
			|| Calendar.class.isAssignableFrom(type)
			|| Boolean.class.equals(type)
			|| Character.class.equals(type);
	}
	
	private boolean isNumeric(Class clazz) {
		return Integer.class.equals(clazz) 
			|| Double.class.equals(clazz) 
			|| Long.class.equals(clazz)
			|| Number.class.equals(clazz);
	}
}

Quando eu deixo as classes diretamente no projeto WEB, o sistema roda tranquilamente.
Contudo, se eu compilo um JAR com as duas classes e adiciono o mesmo na lib do projeto, quando aciono esse classe recebo o seguinte erro:

24/06/2010 16:25:41 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet default threw exception
br.com.caelum.vraptor.InterceptionException: an exception was raised while executing resource method
	at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:86)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:77)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:42)
	at br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.k2studio.vraptor.interceptor.LoginInterceptor.intercept(LoginInterceptor.java:37)
	at br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.InterceptorListPriorToExecutionExtractor.intercept(InterceptorListPriorToExecutionExtractor.java:46)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:81)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:67)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:70)
	at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
	at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:56)
	at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [br.com.k2studio.vraptor.extjs.ExtJSJson] is defined: no bean for this type registered
	at br.com.caelum.vraptor.ioc.spring.VRaptorApplicationContext.getBean(VRaptorApplicationContext.java:255)
	at br.com.caelum.vraptor.ioc.spring.SpringBasedContainer.instanceFor(SpringBasedContainer.java:59)
	at br.com.caelum.vraptor.core.DefaultResult.use(DefaultResult.java:48)
	at br.com.k2studio.vraptor.controller.ExtjsController.combobox(ExtjsController.java:74)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:57)
	... 40 more
24/06/2010 16:25:41 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet default threw exception
br.com.caelum.vraptor.InterceptionException: an exception was raised while executing resource method
	at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:86)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:77)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:42)
	at br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.k2studio.vraptor.interceptor.LoginInterceptor.intercept(LoginInterceptor.java:37)
	at br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.InterceptorListPriorToExecutionExtractor.intercept(InterceptorListPriorToExecutionExtractor.java:46)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:81)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:67)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:70)
	at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
	at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:56)
	at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [br.com.k2studio.vraptor.extjs.ExtJSJson] is defined: no bean for this type registered
	at br.com.caelum.vraptor.ioc.spring.VRaptorApplicationContext.getBean(VRaptorApplicationContext.java:255)
	at br.com.caelum.vraptor.ioc.spring.SpringBasedContainer.instanceFor(SpringBasedContainer.java:59)
	at br.com.caelum.vraptor.core.DefaultResult.use(DefaultResult.java:48)
	at br.com.k2studio.vraptor.controller.ExtjsController.grid(ExtjsController.java:36)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:57)
	... 40 more

Alguém sabe como posso resolver isso?

[]´s
Daniel

5 Respostas

G

se você usar componentes do vraptor dentro de um jar você precisa especificar no seu web.xml o endereço desses pacotes.

<context-param> <param-name>br.com.caelum.vraptor.packages</param-name> <param-value>com.acme.blahhhh</param-value> </context-param>

yorgan

Opa, fiz isso mas não deu certo.

Mais alguma dica?

[]´s

Daniel

G

Você especificou o package br.com.k2studio.vraptor.extjs?

yorgan

Sim, e até mudei o pacote no outro projeto para tirar qualquer semelhança com o projeto web.

Lucas_Cavalcanti

vc gerou o jar com entradas de diretório?

no eclipse, vc tem que marcar um checkbox chamado “include directory entries” ou algo do tipo…

Criado 24 de junho de 2010
Ultima resposta 26 de jun. de 2010
Respostas 5
Participantes 3