3

I'm using JSF 2.1 with CDI and JBoss 7.1.1

Is it possible to inject with CDI in a super class variable principal and cast to derived class ? In example MyUserPrincipal is derived class. If I write @Inject Principal principal I know from debugging (and overloaded toString() method) that MyUserPrincipal proxy class will be injected in the variable principal. But I could not cast this instance to MyUserPrincipal instance.

Below my 2 attempts to solve the problem:

public class MyUserPrincipal implements Principal, Serializible{
   MyUserPrincipal (String name){
   }
   public myMethod() { }
}

//Attempt 1:
public class MyCdiClass2 implements Serializable{
   //MyUserPrincipal proxy instance will be injected. 
   @Inject Principal principal;      

   @PostConstruct init() {
       MyUserPrincipal myPrincipal = (MyUserPrincipal) pincipal;  //<--- Fails to cast! (b)
      myPrincipal.myMethod();
   }
}

//Attempt 2:
public class MyCdiClass1 implements Serializable{
   @Inject MyUserPrincipal myPrincipal; //<---- Fails to inject! (a)

   @PostConstruct init() {
       //do something with myPrincipal

   }
}
Tony
  • 2,266
  • 4
  • 33
  • 54
  • do you have a producer method for MyUserPrincipal? – Adrian Mitev Aug 27 '13 at 07:56
  • No, MyUserPrincipal is initialised in derived from login container class (UsernamePasswordLoginModule) and comes from login container (JBoss-Authentication). – Tony Aug 27 '13 at 11:35

1 Answers1

1

If you do not have a producer, what you're injecting is actually a proxy which extends the container provided principal. Two classes that implement the same interface are assignment compatible to a field whose type is that interface, but you cannot cast one as the other.

That said, it seems you want to override the built-in principal bean. As far as I know, you can only achieve that using alternatives prior to CDI 1.0, and also using decorators in CDI 1.1, see CDI-164.

Alternatives example:

package com.example;

@Alternative
public class MyUserPrincipal implements Principal, Serializible {

    // ...

    @Override
    public String getName() {
        // ...
    }
}

// and beans.xml

<?xml version="1.0" encoding="UTF-8"?>

http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> com.example.MyUserPrincipal

Decorator example:

@Decorator
public class MyUserPrincipal implements Principal, Serializible {

    @Inject @Delegate private Principal delegate;

    // other methods

    @Override
    public String getName() {
        // simply delegate or extend
        return this.delegate.getName();
    }
}

// again plus appropriate beans.xml
rdcrng
  • 3,415
  • 2
  • 18
  • 36