1

I want to inject bean in a Tapestry service (not in a page).

For the moment, I use this :

public class EntityRealm extends AuthorizingRealm {

ApplicationContext ctx = new ClassPathXmlApplicationContext("/application-context-security.xml");
SecurityServices securityServices = (SecurityServices)ctx.getBean("securityServices");

It works, but I want use this :

public class EntityRealm extends AuthorizingRealm {

@Inject
private SecurityServices securityServices;

And my applicationContext is in the web.xml. In this second case, the injection doesn't work. Why ?

AppModule.java :

public class AppModule
{

//@Resource(name = "realm")
@Inject
private static EntityRealm realm;

@Contribute(WebSecurityManager.class)
public static void addRealms(Configuration<EntityRealm> configuration) {

    //EntityRealm realm = new EntityRealm();

    configuration.add(realm);
}

public static void contributeFactoryDefaults( MappedConfiguration<String, Object> configuration)
{
    configuration.override(SecuritySymbols.LOGIN_URL, "/login");
    configuration.override(SecuritySymbols.UNAUTHORIZED_URL, "/login");
    configuration.override(SecuritySymbols.SUCCESS_URL, "/index");
    configuration.override(SymbolConstants.APPLICATION_VERSION, "2.0-SNAPSHOT");
}

public static void contributeApplicationDefaults(MappedConfiguration<String, Object> configuration)
{
    configuration.add(SymbolConstants.HMAC_PASSPHRASE, new BigInteger(130, new SecureRandom()).toString(32));
    configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en,fr");
    configuration.add( "tapestry.default-cookie-max-age", "31536000" ); 
}

public RequestFilter buildTimingFilter(final Logger log)
{
    return new RequestFilter()
    {
        public boolean service(Request request, Response response, RequestHandler handler)
                throws IOException
        {
            long startTime = System.currentTimeMillis();
            try
            {
                return handler.service(request, response);
            } finally
            {
                long elapsed = System.currentTimeMillis() - startTime;

                log.info(String.format("Request time: %d ms", elapsed));
            }
        }
    };
}

public void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration,
                                     @Local
                                     RequestFilter filter)
{
    configuration.add("Timing", filter);
}
}

And the EntityRealm.java :

public class EntityRealm extends AuthorizingRealm {

//***************************************
//************* Attributes  *************
//***************************************   
//ApplicationContext ctx = new ClassPathXmlApplicationContext("/application-context-security.xml");

//SecurityServices securityServices = (SecurityServices)ctx.getBean("securityServices");

//@Resource(name = "securityServices")
@Inject
private SecurityServices securityServices;

//***************************************
//************ Constructors *************
//***************************************

public EntityRealm() {
    super(new MemoryConstrainedCacheManager());
    setName("myapprealm");
    setAuthenticationTokenClass(UsernamePasswordToken.class);

} 

//***************************************
//********** Public Methods *************
//***************************************
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    if (principals == null) throw new AuthorizationException("PrincipalCollection was null, which should not happen");

application-context.xml :

<bean id="realm" class="net.atos.m2m.telecom.ihm.services.EntityRealm">
    <property name="securityServices" ref="securityServices"></property>
</bean> 

<bean id="securityServices" class="net.atos.m2m.telecom.ihm.applicatif.services.security.impl.SecurityServicesImpl">
    <property name="servicesTelSecu" ref="servicesTelSecu"></property>
    <property name="converterSecDSPtoDTO" ref="converterSecDSPtoDTO"></property>
    <property name="converterSecDTOtoDSP" ref="converterSecDTOtoDSP"></property>
</bean>

Can you help me ?

Thank you.

user2007861
  • 407
  • 3
  • 6
  • 17

2 Answers2

3

How i say in previous comment, if you create EntityRealm in this way .. new EntityRealm() the inject\autowire does not work.

You must define EntityRealm as bean .. XML or Annotation.

<bean id="entityRealm" class="package.EntityRealm"/>
<bean id="securityServices" class="package.SecurityServices"/>
Xstian
  • 8,184
  • 10
  • 42
  • 72
  • I have these two beans in my app context file. In my appModule, I inject the entityRealm (see in my first message). When I run the app, I have an exception (Service contribution (to service 'WebSecurityManager') was null). So "realm" is not injected. – user2007861 Aug 13 '14 at 07:19
  • In the other revision of your answear there is EntityRealm realm = new EntityRealm(); and when you create in this way an object, all annotations don't work. what is name of EntityRealm bean? "realm"? if not you should add @Qualifier("realm") – Xstian Aug 13 '14 at 07:25
  • Yes, the name is realm. `@Inject @Qualifier("realm") private static EntityRealm realm;` Always the same, no injection. – user2007861 Aug 13 '14 at 07:40
  • You shouldn't use a static field.. in this case follow this [link](http://stackoverflow.com/a/11324464/3364187) – Xstian Aug 13 '14 at 07:44
  • Is a pleasure to help you :) tell us if you solve the problem :) – Xstian Aug 13 '14 at 07:55
  • I added in app context : ` ` – user2007861 Aug 13 '14 at 08:44
  • And in AppModule.java : `@Inject @Qualifier("realm") private static EntityRealm realm; public static void setRealm(EntityRealm er) { realm = er; } @Contribute(WebSecurityManager.class) public static void addRealms(Configuration configuration) { //EntityRealm realm = new EntityRealm(); configuration.add(realm); } ` I obtain an error : AppModule contains unrecognized public methods (setEntityRealm)... – user2007861 Aug 13 '14 at 08:45
  • change this public static void setRealm(EntityRealm er) in public static void setEntityRealm(EntityRealm er) – Xstian Aug 13 '14 at 08:46
  • I changed realm by entityRealm everywhere (in app context and AppModule.java). `@Inject @Qualifier("entityRealm") private static EntityRealm entityRealm; public static void setEntityRealm(EntityRealm er) { entityRealm = er; }` Error is the same : Module class net.atos.m2m.telecom.ihm.services.AppModule contains unrecognized public methods: public static void net.atos.m2m.telecom.ihm.services.AppModule.setEntityRealm(net.atos.m2m.telecom.ihm.services.EntityRealm). – user2007861 Aug 13 '14 at 08:55
  • If this way don't work, you use a simple set property by xml and set the static field... are you sure that do you want use a static field? .. isn't best practices. – Xstian Aug 13 '14 at 09:02
  • No, i don't want to use static field, but if the field is not static, I have an error here : `@Contribute(WebSecurityManager.class) public static void addRealms(Configuration configuration) { //EntityRealm entityRealm = new EntityRealm(); configuration.add(entityRealm); }` "Cannot make a static reference to the non-static field entityRealm" – user2007861 Aug 13 '14 at 09:07
  • I'm stupid... I removed static here : 'public void addRealms' and it's OK. Thank you very much Xstian. (I wonder why this method is static in the Tynamo documentation..) – user2007861 Aug 13 '14 at 09:11
  • :D is a pleasure, i suggest you to close this issue because the discussion is very long :) – Xstian Aug 13 '14 at 09:34
1

You can use @Resource instead,

@Resource(name = "securityServices")
private SecurityServices securityServices;

And make sure that application-context-security.xml file is loaded by Spring.

Guo Song
  • 352
  • 1
  • 11
  • Than you. With the annotation @Resource, I can't add ("securityServices"). And how verify that the application-context is loaded by Spring ? – user2007861 Aug 12 '14 at 09:42
  • You should add a variable `name`: `@Resource(name = "securityServices")`. – Guo Song Aug 12 '14 at 09:47
  • To verify application-context is loaded, you can check the log information of loading XMLs by Spring when the app is starting. – Guo Song Aug 12 '14 at 09:49
  • Yes, I just tried it, it doesn't work. The result is the same that @Inject : no injection – user2007861 Aug 12 '14 at 09:50
  • The application-context file is loaded : Loading XML bean definitions from ServletContext resource [/WEB-INF/application-context-mock.xml] – user2007861 Aug 12 '14 at 09:52
  • how do you retrieve this object EntityRealm ? if you perform a new EntityRealm() the @Inject does not work. – Xstian Aug 12 '14 at 09:55
  • @user2007861, where is your `SecurityServices` service defined?. If it is defined in a xml file, make sure the file is loaded. – Guo Song Aug 12 '14 at 10:14
  • Yes, the xml file (with securityServices) is loaded. The object EntityRealm is created with a new EntityRealm() in the class AppModule. – user2007861 Aug 12 '14 at 11:47