J2EE 6 Interceptors on Component classes

Im just starting with Vaadin and am stumbling on the current issue with vaadin 7.1.0.beta1. Im using Java 7, JBoss 7 and CDI-Utils addon. I looked around and did not find something specific to my issue.

I created a class which extends VerticalLayout. This class has intercepted methods for logging. When I run it I end up with an NullPointer


14:56:32,818 SEVERE [com.vaadin.server.DefaultErrorHandler]
 (http--0.0.0.0-8080-1) : java.lang.NullPointerException
	at login.NewLoginView$Proxy$_$$_WeldSubclass.getParent(NewLoginView$Proxy$_$$_WeldSubclass.java) [classes:]

	at com.vaadin.ui.AbstractComponent.getParent(AbstractComponent.java:51) [vaadin-server-7.1.0.beta1.jar:7.1.0.beta1]

	at com.vaadin.server.AbstractClientConnector.getUI(AbstractClientConnector.java:457) [vaadin-server-7.1.0.beta1.jar:7.1.0.beta1]

	at login.NewLoginView$Proxy$_$$_WeldSubclass.getUI(NewLoginView$Proxy$_$$_WeldSubclass.java) [classes:]

	at com.vaadin.server.AbstractClientConnector.markAsDirty(AbstractClientConnector.java:138) [vaadin-server-7.1.0.beta1.jar:7.1.0.beta1]

	at login.NewLoginView$Proxy$_$$_WeldSubclass.markAsDirty(NewLoginView$Proxy$_$$_WeldSubclass.java) [classes:]

	at com.vaadin.ui.AbstractComponent.setWidth(AbstractComponent.java:816) [vaadin-server-7.1.0.beta1.jar:7.1.0.beta1]

	at com.vaadin.ui.AbstractComponentContainer.setWidth(AbstractComponentContainer.java:257) [vaadin-server-7.1.0.beta1.jar:7.1.0.beta1]

	at NewLoginView$Proxy$_$$_WeldSubclass.setWidth(NewLoginView$Proxy$_$$_WeldSubclass.java) [classes:]

	at com.vaadin.ui.AbstractComponent.setWidth(AbstractComponent.java:829) [vaadin-server-7.1.0.beta1.jar:7.1.0.beta1]

	at login.NewLoginView$Proxy$_$$_WeldSubclass.setWidth(NewLoginView$Proxy$_$$_WeldSubclass.java) [classes:]

	at com.vaadin.ui.VerticalLayout.<init>(VerticalLayout.java:35) [vaadin-server-7.1.0.beta1.jar:7.1.0.beta1]

Is this use case supported ? If so, I am missing something ?
Many thanks

Bump ! Anyone ?!? Anybody tried using an custom interceptor for logging (as example) on an extension of a custom component of Vaadin 7 ?

Thanks again

I think this problem is not related to CDI. You should set your initialize code in attach method.
But if you provide some listing, maybe there is more help.

Best
Ebrahim Pasbani

It’s quite simple … I practically followed the J2EE 6 spec by the book.

This is the def of the annotation


import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.interceptor.InterceptorBinding;
@Inherited
@InterceptorBinding
@Retention(RUNTIME)
@Target({
    METHOD,
    TYPE
})
public @interface Logged {
}

This is the the annotation implementation


@Logged
@Interceptor
public class LoggedInterceptor implements Serializable {
    private static final long serialVersionUID = 1L;

    public LoggedInterceptor() {
    }

    @AroundInvoke
    public Object logMethodEntry(InvocationContext invocationContext)
        throws Exception {
        System.out.println(
                "Entering method: " + invocationContext.getMethod().getName()
                + " in class "
                + invocationContext.getMethod().getDeclaringClass().getName());

        return invocationContext.proceed();
    }
}

An the code looks like this …



public abstract class BaseComponent<T extends Component> extends CustomComponent {
 private final T component;

    protected BaseComponent(final Class<T> clazz) {
        try
        {
            component = clazz.newInstance();
        } catch (InstantiationException | IllegalAccessException e)
        {
            throw new IllegalStateException("Cannot instantiate a base component of class " + clazz, e);
        }
    }

    @Logged
    protected T getComponent() {
        return component;
    }

    @Logged
    public CustomComponent get() {
        return this;
    }

And this in my bean.xml


<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="
      http://java.sun.com/xml/ns/javaee 
      http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
	<interceptors>
		<class>com.base.LoggedInterceptor</class>
	</interceptors>
</beans>

It’s seems that everything gets proxied within vaadin and as soon that we access “super”, we end up with an exception.

Thanks again

In your original post you mentioned you are using VerticalLayout , yet in your listing above you show a component that extends CustomComponent ?

CustomComponent is somewhat of special case, you must setCompositionRoot(component) somewhere before you try to access parent of component otherwise component is not attached in the hierarchy…

As Petrus mentioned, this listing is not related to your exception stack trace.
Your stack trace is related to creating and initializing an object and not related to interceptor.

Im sorry if I repeat myself a bit, I just really want to get to the bottom of this … And all your help is really appreciated :slight_smile:

We build compositions were T in the case of the custom component is the vertical|horizontal|grid|css|… layout.
Applying the annotation anywhere on the implementation of the abstract component causes the issue.

For example:


public class DashboardView extends BaseView<VerticalLayout> {

    @Inject
    private EventService eventService;
    @Inject
    private LocaleSelection localeSelection;

    protected DashboardView() {
        super(VerticalLayout.class);
        setSizeFull();
    }

    @Override
    protected void setup(final VerticalLayout component) {
        component.setSizeFull();
        Panel panel = new Panel("Hello World");
        component.addComponent(panel);
        component.setComponentAlignment(panel, Alignment.MIDDLE_CENTER);
        doSomething();
    }

    @Logged
    private void doSomething() {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void enter(ViewChangeEvent event) {
        // NoOp
    }

Here BaseView is an extension of BaseComponent which extends CustomComponent.

We have the following in the BaseComponent


    @PostConstruct
    protected final void init() {
        eventService.register(this);

        setCompositionRoot(component);

        setup(component);
    }

which sets the compositionRoot automatically before calling the implementor setup of the component.

The stuff always fails in the Vaadin method ot the AbstractClientConnector


   @Override
    public UI getUI() {
        ClientConnector connector = this;
        while (connector != null) {
            if (connector instanceof UI) {
                return (UI) connector;
            }
            connector = connector.getParent();
        }
        return null;
    }

when the connector.getParent() is called (from getUI())

Connector is the following
com.dashboard.DashboardView$Proxy$_$$_WeldSubclass@e521dc
and DashboardView extends BaseView which extends BaseComponent which extends CustomComponent, so getParent() is implemented in CustomComponent.

The stack indicates this anyway


14:30:01,643 SEVERE [com.vaadin.server.DefaultErrorHandler]
 (http--0.0.0.0-8080-1) : java.lang.NullPointerException
	at com.interfacing.epc.ui.dashboard.DashboardView$Proxy$_$$_WeldSubclass.getParent(DashboardView$Proxy$_$$_WeldSubclass.java) [classes:]

	at com.vaadin.ui.AbstractComponent.getParent(AbstractComponent.java:51) [vaadin-server-7.1.0.beta1.jar:7.1.0.beta1]

	at com.vaadin.server.AbstractClientConnector.getUI(AbstractClientConnector.java:457) [vaadin-server-7.1.0.beta1.jar:7.1.0.beta1]

	at com.interfacing.epc.ui.dashboard.DashboardView$Proxy$_$$_WeldSubclass.getUI(DashboardView$Proxy$_$$_WeldSubclass.java) [classes:]

	at com.vaadin.server.AbstractClientConnector.markAsDirty(AbstractClientConnector.java:138) [vaadin-server-7.1.0.beta1.jar:7.1.0.beta1]

	at com.interfacing.epc.ui.dashboard.DashboardView$Proxy$_$$_WeldSubclass.markAsDirty(DashboardView$Proxy$_$$_WeldSubclass.java) [classes:]

	at com.vaadin.ui.AbstractComponent.setWidth(AbstractComponent.java:816) [vaadin-server-7.1.0.beta1.jar:7.1.0.beta1]

	at com.interfacing.epc.ui.dashboard.DashboardView$Proxy$_$$_WeldSubclass.setWidth(DashboardView$Proxy$_$$_WeldSubclass.java) [classes:]

	at com.vaadin.ui.CustomComponent.<init>(CustomComponent.java:53) [vaadin-server-7.1.0.beta1.jar:7.1.0.beta1]

	at com.interfacing.epc.ui.base.BaseComponent.<init>(BaseComponent.java:33) [classes:]

	at com.interfacing.epc.ui.base.BaseView.<init>(BaseView.java:10) [classes:]

	at com.interfacing.epc.ui.dashboard.DashboardView.<init>(DashboardView.java:23) [classes:]

	at com.interfacing.epc.ui.dashboard.DashboardView$Proxy$_$$_WeldSubclass.<init>(DashboardView$Proxy$_$$_WeldSubclass.java) [classes:]

...

Im trying to figure out why the getParent() method fails within Vaadin
Without the annotation, the issue dissapears (obviously) …

Thanks again

Do you mean by removing interceptor annotation, everything is ok?
And please show how use from DashboardView.

Thanks

It is a matter of when things happen. You are accessing the component’s parent during via something you are doing with the annotations. ( Note sure what part , it is not in the stack trace ).


https://vaadin.com/directory#addon/cdi-utils:vaadin
makes extensive use of CDI and CustomComponent, look at ViewComponent.java and AbstractView.java ,
Tomi
even has Producers for declaratively defined Vaadin components.

But my best advice is to do NOTHING during and defer what ever it is you are doing in to the point after the components are attached to a its parent…

Take special note of when things are initialized , and accessed.

@Petrus getParent is used in constructor of CustomComponent indirectly.
@Patrick I asked that question because if by removing interceptor annotation, problem is disappeared, so you have 2 ways :

  1. remove interceptors from abstract class and put them to child classes
  2. add @Specialized annotation to child of abstract class (BaseComponent)

Took me awhile, but I figured out the issue … 90% of our stuff extends CustomComponent, but the setCompositionRoot was call in a method with @PostConstruct and not the constructor itself. After re-reading the book of Vaadin, I saw this important bit of info …


To create a composite component, you need to inherit the CustomComponent and call the setCompositionRoot() in the constructor to set the composition root component. The root component is typically a layout component that contains multiple components.

My mistake, but the thing that bothers me is the fact that without interceptors, we have no ‘apparent’ issue doing otherwise.

Thanks everybody for the help