Help

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

Work in progress list of enhancements to javax.enterprise.inject and javax.enterprise.context for the CDI 1.0 maintenance release and CDI 1.1.

Clarify that scope types should not have members

The spec should mention that @ScopeType annotations should not have annotation members. Perhaps this should be a definition error. javax.inject.Scope already mentions this.

Static injection

Injection for static members has a couple of problems:

  • A class can be shared between multiple applications, and the Java EE spec does not define rules for this.
  • Outside Java EE, it's difficult to define exactly when a static member is injected.

Nevertheless, there are a couple of great usecases for this:

  • logger injection,
  • injection for entity classes, and
  • injection into objects with a passivating scope.

So we do need to support something here. Perhaps it would be enough to say:

  • no static injection in shared libraries, and
  • static fields are injected before the very first instance of a bean is instantiated (but then static injection would not be supported for non-bean classes).

Additional ambiguous dependency resolution rules

Currently CDI is extremely dependent upon the use of qualifiers for resolving ambiguous dependencies. This is not a bad thing, since too much implicit behavior can result in difficult to trace bugs. However, we should discuss the following:

  • resolving ambiguities in favor of beans in the same module, and/or
  • allowing declaration of alternatives at the package or bean level, in addition to the module level.

Producer constructors

We can allow a bean to be defined by annotating a constructor @Produces, for example:

@Produces @SessionScoped @Special
Foo(@Special Bar bar) { ... }

A class with a @Producer constructor might not have a normal bean constructor.

Abstract producer methods

An abstract method or interface method could define an alias for a bean:

@Produces @Foo Baz foo(@Bar Baz bar);

is a shortcut for @Produces @Foo Baz foo(@Bar Baz bar) { return bar; }. And:

@Produces @Foo Baz foo();

is a shortcut for @Produces @Foo Baz foo(@New Baz bar) { return bar; }.

Limit scanning using beans.xml

We could allow certain packages/classes to be excluded from bean discovery using globs in beans.xml.

Allow a producer to specialize a regular bean

Currently, producers may specialize producers, and regular beans may specialize regular beans. We should allow a producer to specialize a regular bean. The following options seem to work out:

Option 1:

Add a value() to @Specializes.

@Specializes(Foo.class) 
@Produces Foo foo(@New Foo foo) { ..... }

Option 2:

Support @Specializes on any injection point annotated @New.

@Produces Foo foo(@Specializes @New Foo foo) { .... }

Allow injection of Bean object for a bean

Currently we allow injected dependent objects to inject an InjectionPoint. We should also allow beans to inject their own Bean (and Module?), and, in the case of dependent objects, the Bean of the object to which they belong (not all dependent objects are injected).

Support producers with a type variable bean type

The spec says that you can't have a type variable be a bean type. But we can in theory use InjectionPoint to overcome Java's lack of reified generics, to allow the following:

@Produces @Parameter("") 
<T> T getParameter(FacesContext fc, InjectionPoint ip) {
  Class<T> type = (Class<T>) ip.getType();
  String paramName = ip.getAnnotated().getAnnotation(Parameter.class).value();
  //get the parameter value and convert it to the right type
  ...
}

Note that we would have to think extra-hard before relaxing the complementary restriction that an injection point type may not be a type variable (since then you would need the whole stack of InjectionPoints).

4 comments:
 
20. Nov 2009, 14:06 America/New_York | Link
Nevertheless, there are a couple of great usecases for this: logger injection

Gavin, last time we discussed injection into entities you considered logger injection as kinda lame use case. :-) Can we now use this great use case to consider adding injection into entities?

Cheers, RafaƂ

 
20. Nov 2009, 15:40 America/New_York | Link
Rafal Hajdacki wrote on Nov 20, 2009 14:06:
Nevertheless, there are a couple of great usecases for this: logger injection Gavin, last time we discussed injection into entities you considered logger injection as kinda lame use case. :-) Can we now use this great use case to consider adding injection into entities?

Logging is not enough to justify adding non-static injection to entities, since there are plenty of other ways to get a logger that don't involve messing with the whole already-complex entity lifecycle.

Non-static injection for entities has lots of problems, since entities are not truly container-managed objects:

  • their lifecycle begins with a new, and
  • they can be detached (and serialized by the application).

However, it seems to me that static injection neatly solves some of these problems. So the cost/benefit analysis is quite different. And entities are a third good usecase for static injection. Thanks for noticing this.

 

Learn more about Weld...

20. Nov 2009, 16:42 America/New_York | Link

Is it safe to assume you can't inject a value into a static final field? I'm guessing it's a fundamental limitation of Java.

I have a lot of scenarios where I want a semi-constant. I have values I want to expose to static helper methods that will never change once deployed, but we don't necessarily want to have a different compile job for each environment.

For example:

public final MyProjectConstants{
	/** Password Based Encryptor w/ 256-bit SHA and 256-bit AES via Bouncy Castle */
	public static final String ENCRYPTION_ALGORITHM = "PBEWITHSHA256AND256BITAES-CBC-BC";
}

Users may think they want to change the encryption standard based on which environment the war has been deployed to. It would be very unwise on their part, but they are paying the bills and as a result, we must appease them. Essentially, many customers would like to have the power to change properties that really should be static.

Right now, in Spring, I do:

@Component
public final MyProjectConstants{
	@Autowired
	public final MyProjectConstants(@Qualifier(name="encryptionAlgorithm") String encryptionAlgorithm){
		this.encryptionAlgorithm=encryptionAlgorithm;
	}
	public final String encryptionAlgorithm;
}

...and just don't use static helper methods. TMK, the only alternative is to inject a reference to the MyProjectConstants object into static variable and hope it is never called in a JVM that hasn't initialized my IOC container.

I'm expecting there is no solution to this because Java doesn't have the notion of final static variables that can be initialized on startup instead of compile time, such as with values in a Weld container.

20. Nov 2009, 18:24 America/New_York | Link

I think the story goes like this: You can set the value of a final field using reflection if you first call setAccessible(true). But since the JVM can inline static finals, it might not actually have the effect you want - some code will keep using the old field value.

See here.

 

Learn more about Weld...