0

Edit 7:

The problem seems to be how to get @Configurable working with HttpSessionListener, a workaround is suggested, but I'dd prefer not to to interact with the WebApplicationContext directly:

   @Configurable(autowire = Autowire.BY_TYPE, preConstruction = true)
    public class SessionListener implements HttpSessionListener {

        private static final Logger log;

        @Autowired
        private A a;

        @Override
        public void sessionCreated(HttpSessionEvent se) {
            a.doSomething(); // <- Throws NPE
            log.info("New session was created");
        }

        @Override
        public void sessionDestroyed(HttpSessionEvent se) {
            log.info("A session was closed");
        }
    }

Edit 6:

I made the sample project simpler: you can now run it from CLI

  1. download and extract project: http://www.2shared.com/file/KpS5xeqf/dynatable.html
  2. run mvn clean aspectj:compile
  3. run mvn gwt:run
  4. You should see in your CLI that "Why is consumer NULL here?" is printed.
  5. Expected instead is:cunsumer is not NULL!

The end is near :D

Edit 5: Sample project in GWT: pls run this in GWT development mode

http://www.2shared.com/file/eai0PV-5/dynatable.html

You will get a NPE at sessionCreated()

Requirements to run are maven + gwt 2.5

Edit 4:

It seemed the sample project wasn't a very representative one. I should reformulate the problem:

In eclipse I use GWT Development mode when I run the project as a web application. In some way this doesn't call the aspectj compiler. At least that's the only reason I can think of.

Question: How to setup Compile Time Weaving to work with running as web application (GWT Development mode).?

Edit 3:

I made a small sample project in Eclipse 4.2.1, M2e 1.4.0, STS 3.1.0, AJDT 2.2.2 that demonstrates the problem: http://www.2shared.com/file/WZ1T9l9-/autowired.html

Edit 2:

As suggested by other similar topics I took the plugins of a standard generated Roo project to avoid conflicting versions. No success yet. (Updated the org.codehaus.mojo above)

Edit 1:

I'm not sure this is normal, but when I start up the web application, I get a long log of what spring is doing , but nothing mentions any weaving / anything related to Aspectj...

I think the problem is related to this plugin in pom.xml not being compiled as I don't get any feedback in my console(I tried many other similar plugins but none work) It seems the plugin is never called when I run the web application:

<plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>aspectj-maven-plugin</artifactId>
                    <version>1.2</version>
                    <!-- NB: do not use 1.3 or 1.3.x due to MASPECTJ-90 and do not use 1.4 
                        due to declare parents issue -->
                    <dependencies>
                        <!-- NB: You must use Maven 2.0.9 or above or these are ignored (see 
                            MNG-2972) -->
                        <dependency>
                            <groupId>org.aspectj</groupId>
                            <artifactId>aspectjrt</artifactId>
                            <version>1.7.0</version>
                        </dependency>
                        <dependency>
                            <groupId>org.aspectj</groupId>
                            <artifactId>aspectjtools</artifactId>
                            <version>1.7.0</version>
                        </dependency>
                    </dependencies>
                    <executions>
                        <execution>
                            <goals>
                                <goal>compile</goal>
                                <goal>test-compile</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <outxml>true</outxml>
                        <aspectLibraries>
                            <aspectLibrary>
                                <groupId>org.springframework</groupId>
                                <artifactId>spring-aspects</artifactId>
                            </aspectLibrary>
                        </aspectLibraries>
                        <source>1.6</source>
                        <target>1.6</target>
                    </configuration>
                </plugin>

Original Post:

I've been searching stackoverflow and many other resources, but none of their standard solutions help me to find why an @autowired field yields to Null Pointer Exception (NPE) when accessed.

@Configurable(autowire = Autowire.BY_TYPE, preConstruction = true)
public class SessionListener implements HttpSessionListener {

    private static final Logger log;

    @Autowired
    private A a;

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        a.doSomething(); // <- Throws NPE
        log.info("New session was created");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        log.info("A session was closed");
    }
}

The A class is declared as follows:

@Service
public class B implements A {
// some implementation
}

my application context has the relevant parts:

<context:spring-configured />
<context:annotation-config />
<context:component-scan base-package='some.package' />

All necessary libraries are there. I use Spring 3.0.2. Due to my environment, I'm only able to use compile time weaving. I'm also using the Google Plugin to start GWT Development Mode. I'm using ADJT, the Spring Tool Suite, m2Eclipse and Google Plugin. I also installed AJDT configurator for m2e v1.0.

Vjeetje
  • 5,314
  • 5
  • 35
  • 57
  • I've added the ADJT plugin to my project, but still same results. Can anyone guide me to a way to debug this? – Vjeetje Feb 24 '13 at 11:18
  • Could you share the code that creates your A class? – David Welch Feb 24 '13 at 22:55
  • I don't think the problem lies there, as there are several @autowired in the SessionListener, I just abstracted one to make the code more brief. In any case I added one example to the original post. And thanks for the reply! – Vjeetje Feb 24 '13 at 23:44
  • Everything looks right from what I can see. One possible issue could occur if B extends another class or implements any other interfaces (other than A). Could you post more complete code of your project? – David Welch Feb 25 '13 at 00:30
  • It's pretty tough to debug without a complete example. What other properties are being injected? Does B get instantiated when your app starts up? (You can test by setting a breakpoint in B's constructor & seeing if it gets triggered) – David Welch Feb 25 '13 at 00:34
  • B is just a simple class with no parents and A is a simple interface with no parents. I really think it's irrelevant. The B class doesn't occure in any spring xml file, nor does it have any properties being injected. I can also confirm the constructor B is triggered before the NPE). I really think it's more a setup issue. Is there any way to get more feedback from spring / aspectj? Another remark: when I add mode="aspectj" to the , all the transactions fail. – Vjeetje Feb 25 '13 at 02:46
  • 1
    Yeah, sounds like a configuration issue then. You could enable trace debugging, but how you do that depends on the logging abstraction you use. – David Welch Feb 25 '13 at 04:22
  • setting logging to TRACE level didn't reveal anything interesting. – Vjeetje Feb 25 '13 at 14:24
  • I made a small project that demonstrates the problem. – Vjeetje Feb 25 '13 at 18:43
  • Yeah, not going to download an exe :) Post to GitHub? – David Welch Feb 25 '13 at 22:15
  • It's a simple .zip file, where you got the .exe from? :O – Vjeetje Feb 25 '13 at 22:21

1 Answers1

1

Your App.main() method doesn't create an ApplicationContext to begin with (the JUnit test is fine, since it's annotated with @ContextConfiguration). In order to create it programmatically add the following line to your main method:

public class App {      
    public static void main( String[] args ) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("foo/application-context.xml");

        new ServiceTest().doSomething();
    }
}

EDIT1: Static solution below.

There are 2 dependencies missing:

<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-aspects</artifactId>
  <version>${org.springframework.version}</version>
</dependency>
<!-- https://jira.springsource.org/browse/SPR-6819 -->
<dependency>
  <groupId>javax.persistence</groupId>
  <artifactId>persistence-api</artifactId>
  <version>1.0</version>
  <scope>provided</scope>
</dependency>

I've also replaced ajdtBuildDefFile plugin parameter (the file wasn't included in the archive) with:

<includes>
  <include>**/*.java</include>
</includes>

After adjusting pom.xml that way, the compilation and the test passes:

mvn clean aspectj:compile test

EDIT1: This solution relates to dynamic weaving, which isn't the case.

To answer your specific question, add this to your application-context.xml:

<context:load-time-weaver />

An additional runtime argument for the VM will be required as well:

-javaagent:/full/path/to/spring-instrument-3.0.5.RELEASE.jar

EDIT2: In relation to the GWT app

Frankly, I'm not sure why the aspectj plugin doesn't work with your configuration. If you don't mind a quick workaround, then just use the WebApplicationContextUtils:

@Override
public void sessionCreated(HttpSessionEvent se) {       
  consumer = WebApplicationContextUtils.getWebApplicationContext(se.getSession().getServletContext()).getBean(IConsumer.class);
  ...
}
Szymon Jednac
  • 2,969
  • 1
  • 29
  • 43
  • A) Yeah I forgot to mention that the part to execute is the unit test, not the main method. B) As the question asks (I know it got long) I'm only interested in CTW and not LTW because of environment restrictions. – Vjeetje Feb 26 '13 at 18:47
  • 1
    My bad. I've submitted a revised solution. I hope it helps this time. – Szymon Jednac Feb 26 '13 at 21:19
  • Okay this helped me towards a solution, thanks. There are two things left to solve my issue: 1) the sample provided ran here fine too now, but the real project doesn't. Do you mind if I make a small GWT project? I think it has something to do with the fact it is a class implementing HTTPListener. 2) It's a real hastle to use to command prompt to aspecjt:compile and then reimport the project in eclipse. Can you elaborate on why eclipse isn't using aspectj:compile as it seems its using rather java:compile? (I'll post an edit in original post later) – Vjeetje Feb 26 '13 at 22:02
  • I think the problem has to do something with the fact that I have to run the project in GWT Development mode (run as web application) and therefore the java compiler is used instead of aspectj. And I think even if you mvn aspectj:compile beforehand, the run as web app will redo it anyway. The problem is shifted more towards an eclipse than rather spring problem – Vjeetje Feb 26 '13 at 22:44
  • I'm glad I could help. 1) A minimal GWT example won't hurt. Just make sure the problem is reproducible from CLI (replicating your complete dev enviroment will hardly be possible) 2) No need to reimport. You can run any Maven command directly from Eclipse ("Run as -> Run configurations...") 3) You should probably attach aspectj:compile to the process-classes phase in your pom.xml. That way it will be executed after regular "compile" (frankly, I wasn't able to do that, and since the AJDT file was missing I didn't try too hard). – Szymon Jednac Feb 26 '13 at 23:19
  • In any case, running "aspectj:compile" alone is a good way to debug such problems. For example, dependency errors were not visible eariler during standard build. – Szymon Jednac Feb 26 '13 at 23:22
  • Added the gwt maven project giving the NPE. Most resembling to actual project. I'm afraid you can't just check it from CLI as you need to run the server to get the session active. – Vjeetje Feb 27 '13 at 01:24
  • 1
    How about 'mvn gwt:run'? I can't analyze your problem at this moment, but I'll take a look later today. – Szymon Jednac Feb 27 '13 at 11:24
  • I took your request into consideration, the result is shown in the latest edit. – Vjeetje Feb 27 '13 at 14:01
  • You should probably correct the component-scan declaration. It has an incorrect package name. – Szymon Jednac Feb 28 '13 at 17:36
  • Sorry, that was sloppy. But it isn't the point what is was trying to prove. Please change it to , I hope the real problem shows itself now – Vjeetje Feb 28 '13 at 20:40
  • Well, the real problem is that aspectj:compile isn't executed during "process-classes" phase. I'm not sure why (check out my latest edit for a possible workaround). I'll let you know, if I come up with a better solution. – Szymon Jednac Mar 01 '13 at 00:02
  • Yes that's a workable solution, I'dd like to keep the code clean though using 'Configurable'. HttpSessionListener seems to be in conflict with 'Configurable' somehow. – Vjeetje Mar 01 '13 at 00:13
  • I wouldn't call that a "conflict". After all, HttpSessionListener is just a regular class, that's instantiated by the container. If 'aspectj-maven-plugin' got executed properly, then everything would work as expected (dynamic weaving works and launching aspectj:compile does as well). Using WebApplicationContextUtils is an obvious and less elegant solution, but it will work in any enviroment (and there isn't much overhead). – Szymon Jednac Mar 01 '13 at 00:33