开发者

Spring-AOP @Inject with Maven not working only in release builds

I'm using Spring-AOP support to inject references via @Inject into objects not managed by the Spring beanfactory. For instance:

@Configurable(preConstruction=true)
class DefaultContent implements Content 
  {
    @Inject @Nonnull
    private Site site;

    @Inject @Nonnull
    private ModelFactory modelFactory;

    public DefaultContent (final @Nonnull FileObject file)
      {
        resource = modelFactory.createResource(file);   // <--here
      }

I'm using static code weaving.

I think I know all the related technologies well and this indeed works fine... during the normal development cycle (with Maven).开发者_Go百科 Yesterday I prepared a release (with the Maven release plugin) and the binaries in the release seem to fail injection, since I get a NPE at the line marked with 'here'.

To explain better, until yesterday my project was in SNAPSHOT mode (1.0-ALPHA-2-SNAPSHOT). Binaries from the snapshot work. Binaries from 1.0-ALPHA-2, release mode, don't. Binaries in the next snapshot, 1.0-ALPHA-3-SNAPSHOT, work again. The only black hole are the released binaries. Looking with diff, there are no other differences among the SNAPSHOTs and the release but the version labels of the modules.

So far I've excluded that the problem is due to some strange thing during the Maven release process, since the binaries are buggy even when I re-create 1.0-ALPHA-2 from tagged sources in a "plain" build (that is, just mvn clean install). I've also used a Java decompiler to look at the effective source (post-waving) of the faulty class, comparing the code from 1.0-ALPHA-2 and 1.0-ALPHA-3-SNAPSHOT. They look identical. At last, I've compared the binaries (a .war file running within Jetty) and they contain the same items (that is, no missing dependencies, the only difference being my jar files with a different version).

I need some suggestion to understand better this bug because at the moment I don't know what else to try.


I was able to work around it by changing the listed dependency (as well as a few others) into:

@Inject @Nonnull
private Provider<Site> site;

Provider is a way to inject "lazy" dependencies, that must be deferred as

site.get()

Note that I had already used some Provider<> dependencies in my project in the past as I detected myself some unresolvable circular dependency - usually Spring explicitly gives an error notification about them. So this is not a complete answer to my post - consider that when running a SNAPSHOT this change is not required; an unresolvable circular dependency can't be unresolvable or resolvable when an unrelated detail of the project, such as the SNAPSHOT/release version, is changed...

So I suppose I've triggered some bug in Spring AOP. Still, the Provider<> thing is totally acceptable to me.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜