User defined Exceptions

I have this exception

package com.company.myapp.core;

import com.haulmont.cuba.core.global.Logging;
import com.haulmont.cuba.core.global.SupportedByClient;
import com.haulmont.cuba.core.global.validation.CustomValidationException;

@SupportedByClient
@Logging(Logging.Type.BRIEF)
public class ControlledException extends CustomValidationException {

public ControlledException(String message) {
    super(message);
}

}

and this handler

package com.company.myapp.web;

import com.haulmont.cuba.gui.WindowManager;
import com.haulmont.cuba.gui.components.Frame;
import com.haulmont.cuba.gui.exception.AbstractGenericExceptionHandler;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Nullable;

@Component("myapp_ControlledExceptionHandler")
public class ControlledExceptionHandler extends AbstractGenericExceptionHandler {

private String mensaje;

    public ControlledExceptionHandler(String customMensaje) {
        super("com.company.myapp.core.ControlledException");
        mensaje=customMensaje;
        
    }

    @Override
    protected void doHandle(String className, String message, @Nullable Throwable throwable, WindowManager windowManager) {
        windowManager.showNotification("Clave repetida", mensaje, Frame.NotificationType.ERROR);
    }
@Override
protected boolean canHandle(String className, String message, @Nullable Throwable throwable) {
    return StringUtils.containsIgnoreCase(message, "already exist");
}
}

I’m trying to throw from middleware a defined ControlledException with message

-something- already exist

Client should show a notification with message. There is something i dont get here because it doesnt work. Tomcat starts message says:

  Error initializing application
 org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'company_ControlledExceptionHandler' defined in URL [jar:file:/C:/Users/apunz/Documents/MEGAsync/company/Proyectos/DINO/CUBA/myapp/deploy/tomcat/webapps/myapp/WEB-INF/lib/myapp-gui-0.1-SNAPSHOT.jar!/com/campany/myapperp/web/ControlledExceptionHandler.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.String' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
         at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:189) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1193) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1095) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at org.springframework.context.support.ClassPathXmlApplicationContext.<init(ClassPathXmlApplicationContext.java:139) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at org.springframework.context.support.ClassPathXmlApplicationContext.<init(ClassPathXmlApplicationContext.java:93) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at com.haulmont.cuba.core.sys.CubaClassPathXmlApplicationContext.<init(CubaClassPathXmlApplicationContext.java:27) ~[cuba-global-6.8.6.jar:6.8.6]
         at com.haulmont.cuba.core.sys.AbstractAppContextLoader.createApplicationContext(AbstractAppContextLoader.java:90) ~[cuba-global-6.8.6.jar:6.8.6]
         at com.haulmont.cuba.core.sys.AbstractAppContextLoader.initAppContext(AbstractAppContextLoader.java:62) ~[cuba-global-6.8.6.jar:6.8.6]
         at com.haulmont.cuba.core.sys.AbstractWebAppContextLoader.contextInitialized(AbstractWebAppContextLoader.java:75) ~[cuba-global-6.8.6.jar:6.8.6]
         at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4745) [catalina.jar:8.5.23]
         at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5207) [catalina.jar:8.5.23]
         at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:8.5.23]
         at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:752) [catalina.jar:8.5.23]
         at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728) [catalina.jar:8.5.23]
         at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734) [catalina.jar:8.5.23]
         at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1144) [catalina.jar:8.5.23]
         at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1878) [catalina.jar:8.5.23]
         at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_92]
         at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_92]
         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_92]
         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_92]
         at java.lang.Thread.run(Thread.java:745) [na:1.8.0_92]
 Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.String' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
         at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at com.haulmont.cuba.core.sys.CubaDefaultListableBeanFactory.resolveDependency(CubaDefaultListableBeanFactory.java:59) ~[cuba-global-6.8.6.jar:6.8.6]
         at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
         ... 31 common frames omitted

I don’t know what am i doing wrong. Please, some advice. Thanks in advance.

You have included constructor parameter into Spring bean, that is why it is trying to find bean with type String.

You can either remove constructor parameter or define exception handler in XML instead of annotating it with @Component annotation.

1 Like

Thanks for answering so fast. Fixed the String thing. Tomcat now start correctly. But when my defined ControlledException is throwed from Core, at WEB appears this:

> java.lang.ClassNotFoundException: com.company.myapp.core.ControlledException
> 	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1291)
> 	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1119)
> 	at java.lang.Class.forName0(Native Method)
> 	at java.lang.Class.forName(Class.java:348)
> 	at org.apache.commons.lang.ClassUtils.getClass(ClassUtils.java:757)
> 	at org.apache.commons.lang.ClassUtils.getClass(ClassUtils.java:790)
> 	at com.haulmont.cuba.core.sys.serialization.StandardSerialization$1.resolveClass(StandardSerialization.java:65)
> 	at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1620)
> 	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521)
> 	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1781)
> 	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
> 	at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2018)
> 	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1942)
> 	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1808)
> 	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
> 	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
> 	at java.util.ArrayList.readObject(ArrayList.java:791)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> 	at java.lang.reflect.Method.invoke(Method.java:498)

Shared exceptions should be defined in global module, not in core.

1 Like

Ok… then I missunderstood the whole User defined Exception thing. Will try it and I guess it will work now.

It is required because you can deploy core and web applications on different servers. Both modules depend on global module, but web does not depend on core directly.

1 Like

Tested. It works perfectly. :+1:

Exception definition

> package com.company.myapp;
> 
> import com.haulmont.cuba.core.global.Logging;
> import com.haulmont.cuba.core.global.SupportedByClient;
> import com.haulmont.cuba.core.global.validation.CustomValidationException;
> 
> @SupportedByClient
> @Logging(Logging.Type.BRIEF)
> public class ControlledException extends CustomValidationException {
> 
> 	public ControlledException(String message) {
> 		super(message);
> 	}
> 
> }

Handler

> package com.company.myapp.web;
> 
> import com.haulmont.cuba.core.global.validation.CustomValidationException;
> import com.haulmont.cuba.gui.WindowManager;
> import com.haulmont.cuba.gui.components.Frame;
> import com.haulmont.cuba.gui.exception.AbstractGenericExceptionHandler;
> import com.company.ControlledException;
> 
> import org.apache.commons.lang.StringUtils;
> import org.springframework.stereotype.Component;
> 
> import javax.annotation.Nullable;
> 
> @Component("myapp_ControlledExceptionHandler")
> public class ControlledExceptionHandler extends AbstractGenericExceptionHandler {
> 	
> 	public ControlledExceptionHandler() {
> 		super(ControlledException.class.getName());
> 		
> 	}
> 
> 	 @Override
> 	 protected void doHandle(String className, String message, @Nullable Throwable throwable, WindowManager windowManager) {
> 	     windowManager.showNotification("Title", message, Frame.NotificationType.ERROR);
> 	 }
> 	 
> }

Sample snippet

> @Override
> public void onBeforeInsert(Empleados entity, EntityManager entityManager) {
> 	Long codigo=entity.getReferenceCode();
>     if (codigo==null) {
>     	codigo=getNextValue();
> 		    entity.setReferenceCode(codigo);
> 		} else {
>     	if (!existsEmployee(codigo)) {
> 			    while (getCurrentValue()<codigo) {
> 			    	getNextValue();
> 			    }
>     	} else {
> 				throw new ControlledException("Employee already exists");
>     	}
> 		}
>  }