[GLASSFISH-18823] Dynamic injection of custom properties Created: 22/Jun/12  Updated: 12/Aug/13  Resolved: 18/Jun/13

Status: Closed
Project: glassfish
Component/s: cdi
Affects Version/s: 3.1.1_b12
Fix Version/s: future release

Type: Improvement Priority: Minor
Reporter: mkarg Assignee: phil.zampino
Resolution: Won't Fix Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

GF3.1.1 Win7 Pro SP1 (64 Bit) JDK 1.6.0_26



 Description   

Sometimes there is a need to modify properties at runtime, i. e. modifying business level application behaviour changes without restarting the domain. This makes sense for example in public services where a planned outage is not wanted.

This can be done in GF3.1.1 by using custom properties which are looked up using JNDI code.

But JNDI is not as smart as CDI, so one wishes to get injection instead. While the injection works, it is static. This means, the change will not get reflected until a domain restart.

We would be really glad if this would work dynamically, i. e. a modification of a custom property would inject at once without the need to restart the domain or the need to use JNDI code.



 Comments   
Comment by jthoennes [ 04/Jul/12 ]

Hello, is this feasible to be implemented?

Comment by marina vatkina [ 05/Jul/12 ]

I'm not sure if the solution is to be in naming or CDI. Let's start with naming

Comment by Cheng Fang [ 12/Jul/12 ]

Since it works with custom resource lookup, have you tried adding an additional proxy or container custom resource, which looks up the dynamic value of the first resource?

You can inject the proxy resource into your application as usual. But this requires that class to be available to server runtime (outside your application packaging) and thus complicates application configuration.

CDI has a Provider type (http://docs.oracle.com/javaee/6/api/index.html?javax/inject/Provider.html), not sure if it can be configured for the dynamic values.

Comment by mkarg [ 13/Jul/12 ]

Maybe you misunderstood why I suggested this feature: I want to get rid of using JNDI. If I am using CDI to write a provider as you suggested, that provider in turn has to use JNDI again. So what did I win? Just even more work and a much complexer solution. But the target is to have LESS work and REDUCE complexity. So CDI certainly will remove JNDI from my bean, but it will simply move it to another bean.

Comment by Cheng Fang [ 13/Jul/12 ]

It's the spec requirement that injection happens only once for the entire life of a component,and it happens at the beginning of its lifecycle. If you want dynamic values, it will need to be implmented by your custom resource type, e.g., via lookup.

Comment by Cheng Fang [ 13/Jul/12 ]

Transfer to cdi for evaluation.

Comment by mkarg [ 16/Jul/12 ]

This might be true for completely selfdeveloped custom types, but it could be implemented into that types that GlassFish ships with already. That means, the fact that CDI forces one-time injection does not prevent the GlassFish-custom-types from working dynamically inside themselves.

Comment by jjsnyder83 [ 29/Oct/12 ]

Could you provide an example of what you want?

Comment by mkarg [ 08/Dec/12 ]

Here is an example scenario:

An EAR-packaged application might need to have a switch that enables or disabled one particular business process (like a boolean for "this feature is enabled"). For example, the process could be that data is to be synchronized between the application and an external data source or sink (like another external application). If the EAR-customer also runs that external application, he switches this sync feature on (if he likes). Otherwise, he switches this feature off (= the default).

Possibly, the EAR-packaged application is used 24x7, and he wants to switch on the sync feature, there is no time to shutdown the container to trigger a CDI-reinjection of the boolean. But to simplify coding, the EAR-vendor does not like to use JNDI (which would be "live"). So my proposal to get "live" values in CDI would be that GlassFish for this reason comes with an implementation of custom properties that are injectable, but that will update "live" under the hood.

Here is how GlassFish could do that:

A solution could be that the static instance (here: boolean value) that is getting CDI-injected is a dynamic wrapper around JNDI but not just a Java primitive. This means, PrimitivesAndStringFactory will in fact not provide a copy of primitive value (boolean), but a reference (hence, java.lang.Boolean), where the reference is always the same but simply either points to the customized value or uses DynamicProxy API, ASM API, or whatever tweak to get a dynamic resolution of the value (e. g. using JNDI internally). That reference is statically injected, but as it is not a copy but a "living" object, it will dynamically reflect any value changes "live".

Example:

@Inject Boolean myValue; // GlassFish injects an object that looks like a Boolean but actually will use JNDI to always return the latest "live" value when any of java.lang.Boolean's methods are invokes.

A different solution could be that CDI injects at the moment the EJB component is getting from the pool instead of when being constructed. That way, a GlassFish factory could simply lookup the value each time the factory is triggered, hence, every time the EJB is taken out of the pool.

Comment by jjsnyder83 [ 18/Jun/13 ]

I think what you're looking for is a portable extension that defines beans for properties. The bean implementations either use jndi, jmx, or something else to lookup the value of the property each time it's accessed. Please check DeltaSpike to see if someone has already written an extension to do this.

CDI requires a scope for objects that it manages so that it knows when to create a new instance under the covers (anything but @Dependent is proxied so that when the injected proxy is access CDI can get the correct instance based on the scope of the injected object.)

Generated at Tue Jun 30 17:54:56 UTC 2015 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.