7 Replies Latest reply on Oct 26, 2006 5:39 PM by zzjb

    All injections are disinjected when used in a component with

    zzjb

      When I use @In and @Unwrap in the same seam component, all the injections are null (at least in the @unwrap method).

      Seems in BijectionInterceptor class, all be disinjected just after inject to the component.

      @AroundInvoke
      public Object bijectTargetComponent(InvocationContext invocation) throws Exception
      {
      if ( getComponent().needsInjection() ) //only needed to hush the log message
      {
      if ( log.isTraceEnabled() )
      {
      log.trace("injecting dependencies of: " + getComponent().getName());
      }
      getComponent().inject( invocation.getTarget(), !isLifecycleMethod( invocation.getMethod() ) );
      }

      Object result = invocation.proceed();

      if ( getComponent().needsOutjection() ) //only needed to hush the log message
      {
      if ( log.isTraceEnabled() )
      {
      log.trace("outjecting dependencies of: " + getComponent().getName());
      }
      getComponent().outject( invocation.getTarget(), !isLifecycleMethod( invocation.getMethod() ) );
      }

      if ( getComponent().needsInjection() ) //only needed to hush the log message
      {
      if ( log.isTraceEnabled() )
      {
      log.trace("disinjecting dependencies of: " + getComponent().getName());
      }
      getComponent().disinject( invocation.getTarget() );
      }

      return result;
      }

      It works fine with components which do not have @Unwrap. Does anyone have idea about this? Thanks a lot.

        • 1. Re: All injections are disinjected when used in a component
          gavin.king

          I can't reproduce this, the following works just fine for me:

          @Name("username")
          public class Username
          {
           @In User user;
          
           @Unwrap
           public String get()
           {
           return user.getUsername();
           }
          }


          • 2. Re: All injections are disinjected when used in a component
            zzjb

            Gavin,

            It's my bad. The @in works fine with @unwrap. The real question is I defined some inside class and @in not work in that case. In before I defined the class in @unwrap, now I move it out.

            @Scope(ScopeType.EVENT)
            @Name("taskListTest")
            public class TaskListTest {
            private CustomMap map;
            @In (create=true)
            private User lgactor;
            public Map getTestMap() {
            if (map == null) {
            map = new CustomMap();
            map.registerExecutionListener(new MapExcecutionListener(){
            public Object perform(Object key) {
            return lgactor.getId();
            }
            });
            }
            return map;
            }
            }

            public class CustomMap extends AbstractMap implements Serializable{
            private HashMap<String, Object> localMap;
            private MapExcecutionListener listener;

            public void registerExecutionListener(MapExcecutionListener listener) {
            this.listener = listener;
            }

            @Override
            public Set entrySet() {
            throw new UnsupportedOperationException();
            }

            @Override
            public Object get(Object key) {
            if (this.listener == null) return null;
            if (localMap == null) localMap = new HashMap<String, Object>();
            else if (localMap.containsKey(key)) return localMap.get(key);
            Object obj = listener.perform(key);
            localMap.put(key.toString(), obj);
            return obj;
            }

            }
            public interface MapExcecutionListener {

            public Object perform(Object key);

            }

            The lgactor is null in the sample code. Could I use @in in that way? Thanks.

            Zhong

            • 3. Re: All injections are disinjected when used in a component
              gavin.king

              Change your code to this:

              @Scope(ScopeType.EVENT)
              @Name("taskListTest")
              public class TaskListTest {
               private CustomMap map;
               @In (create=true)
               private User lgactor;
              
               public Map getTestMap() {
               final User lgactor = this.lgactor;
               if (map == null) {
               map = new CustomMap();
               map.registerExecutionListener(new MapExcecutionListener(){
               public Object perform(Object key) {
               return lgactor.getId();
               }
               });
               }
               return map;
               }
              }



              • 4. Re: All injections are disinjected when used in a component
                zzjb

                Gavin,

                I added the one statement line, but it still doesn't work. With the old seam jar (July 2006), the code works fine. But after build with the lastest code, it has this "null pointer" error. It seems related to the new disinjection. Is there any change will cause that?

                Thanks in advance.

                Zhong

                • 5. Re: All injections are disinjected when used in a component
                  zzjb

                  Gavin,

                  Sorry, my mistake again. It works now. Thanks.

                  Is seam stricter than before about the variable definition? Since the old jar works fine.

                  Zhong

                  • 6. Re: All injections are disinjected when used in a component
                    gavin.king

                    Seam did not used to do "disinjection". It does now. You should not expect injected values to be available outside the scope of an invocation.

                    • 7. Re: All injections are disinjected when used in a component
                      zzjb

                      but inner classes should have full access to outer classes (fields/methods), right? and I define an User variable and assign some value in constructor, it works fine in the inner class. the difference is @In or not.