[JBoss JIRA] (CDI-552) Add support for injection, decorators and interceptors on "new-ed" objects
by Frigo Coder (Jira)
[ https://issues.jboss.org/browse/CDI-552?page=com.atlassian.jira.plugin.sy... ]
Frigo Coder edited comment on CDI-552 at 10/11/18 9:12 AM:
-----------------------------------------------------------
This is a very desired feature that would be useful in several scenarios:
- Migrating legacy code
- Weld SE applications
- Rich domain objects
- OOP applications with advanced features
A proxy based solution would be preferable to maintain consistency with CDI, however this would interfere with direct field access. Runtime weaving solutions are also possible with AspectJ, JavaAgent, or ClassLoader hacks. The new keyword would be optimal, but helper functions or classes are also acceptable.
I have a toy implementation that only approximates the real thing with severe limitations obviously:
{code:java}
public class Manual<T> implements AutoCloseable {
/**
* Does not support constructor interceptors
*/
public static <T> Manual<T> from(T instance) {
return new Manual<>(instance);
}
/**
* Does not support constructor parameters
*/
public static <T> Manual<T> create(Class<T> clazz) {
return new Manual<>(clazz);
}
private BeanManager bm;
private CreationalContext<T> ctx;
private InjectionTargetFactory<T> itf;
private InjectionTarget<T> it;
private InterceptionFactory<T> ifm;
private T instance;
private T proxy;
@SuppressWarnings("unchecked")
private Manual(T instance) {
prepare((Class<T>) instance.getClass());
process(instance);
}
private Manual(Class<T> clazz) {
prepare(clazz);
process(it.produce(ctx));
}
private void prepare(Class<T> clazz) {
bm = CDI.current().getBeanManager();
ctx = bm.createCreationalContext(null);
itf = bm.getInjectionTargetFactory(bm.createAnnotatedType(clazz));
// itf.configure(); // this fucks up things
it = itf.createInjectionTarget(null);
ifm = bm.createInterceptionFactory(ctx, clazz);
ifm.configure();
}
private void process(T object) {
this.instance = object;
it.inject(instance, ctx);
it.postConstruct(instance);
proxy = ifm.createInterceptedInstance(instance);
}
@Override
public void close() {
it.preDestroy(instance);
it.dispose(instance);
ctx.release();
}
@Override
protected void finalize() throws Throwable {
it.preDestroy(instance);
it.dispose(instance);
ctx.release();
super.finalize();
}
/**
* Neither of them supports direct field access due to proxy
*/
public T get() {
return proxy;
}
}
{code}
was (Author: frigocoder):
This is a very desired feature that would be useful in several scenarios:
- Migrating legacy code
- Weld SE applications
- Rich domain objects
- OOP applications with advanced features
A proxy based solution would be preferable to maintain consistency with CDI, however this would interfere with direct field access. Runtime weaving solutions are also possible with AspectJ, JavaAgent, or ClassLoader hacks. The new keyword would be optimal, but helper functions or classes are also acceptable.
I have a toy implementation that only approximates the real thing with severe limitations obviously:
{{public class Manual<T> implements AutoCloseable {
/**
* Does not support constructor interceptors
*/
public static <T> Manual<T> from(T instance) {
return new Manual<>(instance);
}
/**
* Does not support constructor parameters
*/
public static <T> Manual<T> create(Class<T> clazz) {
return new Manual<>(clazz);
}
private BeanManager bm;
private CreationalContext<T> ctx;
private InjectionTargetFactory<T> itf;
private InjectionTarget<T> it;
private InterceptionFactory<T> ifm;
private T instance;
private T proxy;
@SuppressWarnings("unchecked")
private Manual(T instance) {
prepare((Class<T>) instance.getClass());
process(instance);
}
private Manual(Class<T> clazz) {
prepare(clazz);
process(it.produce(ctx));
}
private void prepare(Class<T> clazz) {
bm = CDI.current().getBeanManager();
ctx = bm.createCreationalContext(null);
itf = bm.getInjectionTargetFactory(bm.createAnnotatedType(clazz));
// itf.configure(); // this fucks up things
it = itf.createInjectionTarget(null);
ifm = bm.createInterceptionFactory(ctx, clazz);
ifm.configure();
}
private void process(T object) {
this.instance = object;
it.inject(instance, ctx);
it.postConstruct(instance);
proxy = ifm.createInterceptedInstance(instance);
}
@Override
public void close() {
it.preDestroy(instance);
it.dispose(instance);
ctx.release();
}
@Override
protected void finalize() throws Throwable {
it.preDestroy(instance);
it.dispose(instance);
ctx.release();
super.finalize();
}
/**
* Neither of them supports direct field access due to proxy
*/
public T get() {
return proxy;
}
}
}}
> Add support for injection, decorators and interceptors on "new-ed" objects
> --------------------------------------------------------------------------
>
> Key: CDI-552
> URL: https://issues.jboss.org/browse/CDI-552
> Project: CDI Specification Issues
> Issue Type: Feature Request
> Components: Beans, Decorators, Interceptors, Resolution
> Affects Versions: 2.0-EDR1
> Reporter: Rogerio Liesenfeld
> Priority: Major
>
> The current CDI programming model is not friendly to object-oriented code or proper class design, and does not support true POJOs.
> With this I mean:
> 1) For object-oriented code, I need to be able to instantiate and use *stateful*, short-lived, objects, while still having @Inject fields in it. I shouldn't be forced to have a stateless (non-OO) class (ie, a [Transaction Script|http://martinfowler.com/eaaCatalog/transactionScript.html]).
> 2) Most classes in a business app are not meant to be used as subclasses, ie, they are not designed for extension; therefore, I should be able to make them {{final}} (see http://lcsd05.cs.tamu.edu/slides/keynote.pdf, page 26, or item 17 in the [book|http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683]).
> 3) For a class to truly be a POJO, I must be able to make *full use* of the Java language when designing and implementing it; arbitrary constraints like "can't be final", "can't have final instance fields", "cannot be instantiated directly", etc. prevent it from being a "plain-old" Java object.
> Specifically, what I want is to be able to write the following in a JSF/CDI backing bean for a web UI:
> {code}
> MyBusinessService businessOp = new MyBusinessService(fieldFromUI1, fieldFromUI2, listWithMoreDataFromUI);
> businessOp.performSomeBusinessOperation(otherArgs);
> String result1 = businessOp.getResultXyz();
> List<result> moreResultData = businessOp.getFinalData();
> {code}
> ... while having MyBusinessService be a CDI bean containing one or more @Inject/@PersistenceContext fields (typically, an EntityManager and perhaps other service beans).
> Without this ability, application developers are forced to create procedural Transation Scripts (stateless service class, which tend to have low cohesion).
> For a CDI implementation to do this, it will need to use the java.lang.instrument API, like others tools (AspectJ, JBoss AOP, JBoss Byteman, JaCoCo, JMockit) already do.
> Also, for reference, the Spring framework already supports it for some time: http://docs.spring.io/spring/docs/3.0.0.M3/spring-framework-reference/htm...
--
This message was sent by Atlassian Jira
(v7.12.1#712002)
6 years, 2 months
[JBoss JIRA] (CDI-552) Add support for injection, decorators and interceptors on "new-ed" objects
by Frigo Coder (Jira)
[ https://issues.jboss.org/browse/CDI-552?page=com.atlassian.jira.plugin.sy... ]
Frigo Coder edited comment on CDI-552 at 10/11/18 9:11 AM:
-----------------------------------------------------------
This is a very desired feature that would be useful in several scenarios:
- Migrating legacy code
- Weld SE applications
- Rich domain objects
- OOP applications with advanced features
A proxy based solution would be preferable to maintain consistency with CDI, however this would interfere with direct field access. Runtime weaving solutions are also possible with AspectJ, JavaAgent, or ClassLoader hacks. The new keyword would be optimal, but helper functions or classes are also acceptable.
I have a toy implementation that only approximates the real thing with severe limitations obviously:
{{public class Manual<T> implements AutoCloseable {
/**
* Does not support constructor interceptors
*/
public static <T> Manual<T> from(T instance) {
return new Manual<>(instance);
}
/**
* Does not support constructor parameters
*/
public static <T> Manual<T> create(Class<T> clazz) {
return new Manual<>(clazz);
}
private BeanManager bm;
private CreationalContext<T> ctx;
private InjectionTargetFactory<T> itf;
private InjectionTarget<T> it;
private InterceptionFactory<T> ifm;
private T instance;
private T proxy;
@SuppressWarnings("unchecked")
private Manual(T instance) {
prepare((Class<T>) instance.getClass());
process(instance);
}
private Manual(Class<T> clazz) {
prepare(clazz);
process(it.produce(ctx));
}
private void prepare(Class<T> clazz) {
bm = CDI.current().getBeanManager();
ctx = bm.createCreationalContext(null);
itf = bm.getInjectionTargetFactory(bm.createAnnotatedType(clazz));
// itf.configure(); // this fucks up things
it = itf.createInjectionTarget(null);
ifm = bm.createInterceptionFactory(ctx, clazz);
ifm.configure();
}
private void process(T object) {
this.instance = object;
it.inject(instance, ctx);
it.postConstruct(instance);
proxy = ifm.createInterceptedInstance(instance);
}
@Override
public void close() {
it.preDestroy(instance);
it.dispose(instance);
ctx.release();
}
@Override
protected void finalize() throws Throwable {
it.preDestroy(instance);
it.dispose(instance);
ctx.release();
super.finalize();
}
/**
* Neither of them supports direct field access due to proxy
*/
public T get() {
return proxy;
}
}
}}
was (Author: frigocoder):
This is a very desired feature that would be useful in several scenarios:
- Migrating legacy code
- Weld SE applications
- Rich domain objects
- OOP applications with advanced features
A proxy based solution would be preferable to maintain consistency with CDI, however this would interfere with direct field access. Runtime weaving solutions are also possible with AspectJ, JavaAgent, or ClassLoader hacks. The new keyword would be optimal, but helper functions or classes are also acceptable.
I have a toy implementation that only approximates the real thing with severe limitations obviously:
public class Manual<T> implements AutoCloseable {
/**
* Does not support constructor interceptors
*/
public static <T> Manual<T> from(T instance) {
return new Manual<>(instance);
}
/**
* Does not support constructor parameters
*/
public static <T> Manual<T> create(Class<T> clazz) {
return new Manual<>(clazz);
}
private BeanManager bm;
private CreationalContext<T> ctx;
private InjectionTargetFactory<T> itf;
private InjectionTarget<T> it;
private InterceptionFactory<T> ifm;
private T instance;
private T proxy;
@SuppressWarnings("unchecked")
private Manual(T instance) {
prepare((Class<T>) instance.getClass());
process(instance);
}
private Manual(Class<T> clazz) {
prepare(clazz);
process(it.produce(ctx));
}
private void prepare(Class<T> clazz) {
bm = CDI.current().getBeanManager();
ctx = bm.createCreationalContext(null);
itf = bm.getInjectionTargetFactory(bm.createAnnotatedType(clazz));
// itf.configure(); // this fucks up things
it = itf.createInjectionTarget(null);
ifm = bm.createInterceptionFactory(ctx, clazz);
ifm.configure();
}
private void process(T object) {
this.instance = object;
it.inject(instance, ctx);
it.postConstruct(instance);
proxy = ifm.createInterceptedInstance(instance);
}
@Override
public void close() {
it.preDestroy(instance);
it.dispose(instance);
ctx.release();
}
@Override
protected void finalize() throws Throwable {
it.preDestroy(instance);
it.dispose(instance);
ctx.release();
super.finalize();
}
/**
* Neither of them supports direct field access due to proxy
*/
public T get() {
return proxy;
}
}
> Add support for injection, decorators and interceptors on "new-ed" objects
> --------------------------------------------------------------------------
>
> Key: CDI-552
> URL: https://issues.jboss.org/browse/CDI-552
> Project: CDI Specification Issues
> Issue Type: Feature Request
> Components: Beans, Decorators, Interceptors, Resolution
> Affects Versions: 2.0-EDR1
> Reporter: Rogerio Liesenfeld
> Priority: Major
>
> The current CDI programming model is not friendly to object-oriented code or proper class design, and does not support true POJOs.
> With this I mean:
> 1) For object-oriented code, I need to be able to instantiate and use *stateful*, short-lived, objects, while still having @Inject fields in it. I shouldn't be forced to have a stateless (non-OO) class (ie, a [Transaction Script|http://martinfowler.com/eaaCatalog/transactionScript.html]).
> 2) Most classes in a business app are not meant to be used as subclasses, ie, they are not designed for extension; therefore, I should be able to make them {{final}} (see http://lcsd05.cs.tamu.edu/slides/keynote.pdf, page 26, or item 17 in the [book|http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683]).
> 3) For a class to truly be a POJO, I must be able to make *full use* of the Java language when designing and implementing it; arbitrary constraints like "can't be final", "can't have final instance fields", "cannot be instantiated directly", etc. prevent it from being a "plain-old" Java object.
> Specifically, what I want is to be able to write the following in a JSF/CDI backing bean for a web UI:
> {code}
> MyBusinessService businessOp = new MyBusinessService(fieldFromUI1, fieldFromUI2, listWithMoreDataFromUI);
> businessOp.performSomeBusinessOperation(otherArgs);
> String result1 = businessOp.getResultXyz();
> List<result> moreResultData = businessOp.getFinalData();
> {code}
> ... while having MyBusinessService be a CDI bean containing one or more @Inject/@PersistenceContext fields (typically, an EntityManager and perhaps other service beans).
> Without this ability, application developers are forced to create procedural Transation Scripts (stateless service class, which tend to have low cohesion).
> For a CDI implementation to do this, it will need to use the java.lang.instrument API, like others tools (AspectJ, JBoss AOP, JBoss Byteman, JaCoCo, JMockit) already do.
> Also, for reference, the Spring framework already supports it for some time: http://docs.spring.io/spring/docs/3.0.0.M3/spring-framework-reference/htm...
--
This message was sent by Atlassian Jira
(v7.12.1#712002)
6 years, 2 months
[JBoss JIRA] (CDI-552) Add support for injection, decorators and interceptors on "new-ed" objects
by Frigo Coder (Jira)
[ https://issues.jboss.org/browse/CDI-552?page=com.atlassian.jira.plugin.sy... ]
Frigo Coder commented on CDI-552:
---------------------------------
This is a very desired feature that would be useful in several scenarios:
- Migrating legacy code
- Weld SE applications
- Rich domain objects
- OOP applications with advanced features
A proxy based solution would be preferable to maintain consistency with CDI, however this would interfere with direct field access. Runtime weaving solutions are also possible with AspectJ, JavaAgent, or ClassLoader hacks. The new keyword would be optimal, but helper functions or classes are also acceptable.
I have a toy implementation that only approximates the real thing with severe limitations obviously:
public class Manual<T> implements AutoCloseable {
/**
* Does not support constructor interceptors
*/
public static <T> Manual<T> from(T instance) {
return new Manual<>(instance);
}
/**
* Does not support constructor parameters
*/
public static <T> Manual<T> create(Class<T> clazz) {
return new Manual<>(clazz);
}
private BeanManager bm;
private CreationalContext<T> ctx;
private InjectionTargetFactory<T> itf;
private InjectionTarget<T> it;
private InterceptionFactory<T> ifm;
private T instance;
private T proxy;
@SuppressWarnings("unchecked")
private Manual(T instance) {
prepare((Class<T>) instance.getClass());
process(instance);
}
private Manual(Class<T> clazz) {
prepare(clazz);
process(it.produce(ctx));
}
private void prepare(Class<T> clazz) {
bm = CDI.current().getBeanManager();
ctx = bm.createCreationalContext(null);
itf = bm.getInjectionTargetFactory(bm.createAnnotatedType(clazz));
// itf.configure(); // this fucks up things
it = itf.createInjectionTarget(null);
ifm = bm.createInterceptionFactory(ctx, clazz);
ifm.configure();
}
private void process(T object) {
this.instance = object;
it.inject(instance, ctx);
it.postConstruct(instance);
proxy = ifm.createInterceptedInstance(instance);
}
@Override
public void close() {
it.preDestroy(instance);
it.dispose(instance);
ctx.release();
}
@Override
protected void finalize() throws Throwable {
it.preDestroy(instance);
it.dispose(instance);
ctx.release();
super.finalize();
}
/**
* Neither of them supports direct field access due to proxy
*/
public T get() {
return proxy;
}
}
> Add support for injection, decorators and interceptors on "new-ed" objects
> --------------------------------------------------------------------------
>
> Key: CDI-552
> URL: https://issues.jboss.org/browse/CDI-552
> Project: CDI Specification Issues
> Issue Type: Feature Request
> Components: Beans, Decorators, Interceptors, Resolution
> Affects Versions: 2.0-EDR1
> Reporter: Rogerio Liesenfeld
> Priority: Major
>
> The current CDI programming model is not friendly to object-oriented code or proper class design, and does not support true POJOs.
> With this I mean:
> 1) For object-oriented code, I need to be able to instantiate and use *stateful*, short-lived, objects, while still having @Inject fields in it. I shouldn't be forced to have a stateless (non-OO) class (ie, a [Transaction Script|http://martinfowler.com/eaaCatalog/transactionScript.html]).
> 2) Most classes in a business app are not meant to be used as subclasses, ie, they are not designed for extension; therefore, I should be able to make them {{final}} (see http://lcsd05.cs.tamu.edu/slides/keynote.pdf, page 26, or item 17 in the [book|http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683]).
> 3) For a class to truly be a POJO, I must be able to make *full use* of the Java language when designing and implementing it; arbitrary constraints like "can't be final", "can't have final instance fields", "cannot be instantiated directly", etc. prevent it from being a "plain-old" Java object.
> Specifically, what I want is to be able to write the following in a JSF/CDI backing bean for a web UI:
> {code}
> MyBusinessService businessOp = new MyBusinessService(fieldFromUI1, fieldFromUI2, listWithMoreDataFromUI);
> businessOp.performSomeBusinessOperation(otherArgs);
> String result1 = businessOp.getResultXyz();
> List<result> moreResultData = businessOp.getFinalData();
> {code}
> ... while having MyBusinessService be a CDI bean containing one or more @Inject/@PersistenceContext fields (typically, an EntityManager and perhaps other service beans).
> Without this ability, application developers are forced to create procedural Transation Scripts (stateless service class, which tend to have low cohesion).
> For a CDI implementation to do this, it will need to use the java.lang.instrument API, like others tools (AspectJ, JBoss AOP, JBoss Byteman, JaCoCo, JMockit) already do.
> Also, for reference, the Spring framework already supports it for some time: http://docs.spring.io/spring/docs/3.0.0.M3/spring-framework-reference/htm...
--
This message was sent by Atlassian Jira
(v7.12.1#712002)
6 years, 2 months
Jakarta EE Community Interview for CodeOne/EclipseCon
by David Blevins
Hello everyone,
EclipseCon and CodeOne (formerly JavaOne) are coming up on the 22nd of October. Normally at these events there are keynote statements dedicated to Java EE which usually included messaging around technical goals, roadmap, focus area. In addition there are panels were people ask questions and look for information. News outlets write articles, quoting people and hint at what may come.
All these things should happen, but they should come from voices in the community. That's what this long email is about.
I've created a document where everyone can contribute. It's an interview style so people can potentially reuse the material in articles or blog posts to further support Jakarta EE. Ideally you both contribute to the document and maybe write a blog post or two your own. Consider it a community interview of sorts.
The goal is not hard commitments, but to get people excited and help bring contributors in to add more muscle to fuel our "truly open source Java EE" dreams. If you want people to come help you get something done, use this to write to them and motivate them.
- https://docs.google.com/document/d/1y-Vs4d9Iotw0HqsiTxG5UCm7ua0w35vJZkGVm... <https://docs.google.com/document/d/1y-Vs4d9Iotw0HqsiTxG5UCm7ua0w35vJZkGVm...>
There are four questions. Answer one or all four. Whatever you want. You are encouraged to share it and help get participation.
There are two goals:
- Get this in front of the Jakarta EE Steering Committee as the "voice of the people"
- Get this in front of the press.
I have two deadlines to make sure all the best things can happen:
DEADLINE for inclusion any officially prepared Working Group statements: Friday, October 12th, 11pm Pacific
DEADLINE for realistic inclusion any third party Jakarta EE news coverage Friday, October 19th, 11pm Pacific
The first deadline is with the idea that if people get me content by Friday, I could prepare something over the weekend and have some potential text to share with the Steering Committee meeting that Tuesday morning. The Tuesday 16th meeting will be our last meeting before CodeOne/EclipseCon so that's my last chance to get something in front of everyone for any sort of pre-conference approval. "Approval" really means making sure we get up on stage and say the same thing, despite half of us will be at EclipseCon and the other half at CodeOne. Your thoughts should be presented.
The second deadline is with the thought that our friends and allies in places like JAXEnter would at least have the weekend to come up with any articles they might want to publish when the conferences start the following Monday.
Of course, this could all be too ambitious and no one participates, in which case, I'm ok being the guy with egg on his face. You miss 100% of the shots you don't take. So I'm fine going for it.
That said, I think we can do it and I'd love to see as many voices as we can possibly get.
I can't stress enough -- all voices are welcome. If for a second you think, "I'm nobody, no one wants to hear from me." Bury that thought, yes we do. How does a community of 10 become a community of 100? Only through the bravery of 90 people in your shoes. When we get to 1000, it will be because of you.
If you want that future for us, now is the time to ignore the butterflies and take that risk. Make Jakarta EE the place you believe it can be. You don't have to speak confidently, just speak. The confidence comes with time. You are surrounded by a community who wants you and us all, to succeed. Let's take the first of many brave steps.
-David
--
David Blevins
http://twitter.com/dblevins
http://www.tomitribe.com
6 years, 2 months
CDI context propagation? Maybe in MP Concurrency...
by Matej Novotny
Hi all,
you may or may not have noticed MicroProfile Concurrency spec (MP Conc) which recently came into existence.
The reason why I am bringing this up is CDI context propagation - a topic which, among others, they aim to address in MP Conc spec.
I know this was discussed several times within CDI spec and was declined/deferred and probably with good reasons too ;)
However, now it seems that they are seeking to push this forward and provide some support for it.
And because CDI spec offers pretty much no limitations/guidelines to context propagation, the expectations will have to be baked into MP Conc spec.
Therefore we, as in CDI-folks, should probably keep an eye on that, provide feedback, use cases, corner cases etc.
Basically help shape it somewhat, as later on this may make it's way even into CDI spec itself.
So if any of you are interested in this topic, here is a bunch of links:
GH link - https://github.com/eclipse/microprofile-concurrency
Gitter - https://gitter.im/eclipse/microprofile-concurrency
MP mtgs calendar - https://calendar.google.com/calendar/embed?src=gbnbc373ga40n0tvbl88nkc3r4...
Best regards
Matej
6 years, 2 months
[JBoss JIRA] (CDI-724) Transactional observers fired in inconsistent manner when synchronisation cannot be placed
by Matej Novotny (Jira)
[ https://issues.jboss.org/browse/CDI-724?page=com.atlassian.jira.plugin.sy... ]
Matej Novotny commented on CDI-724:
-----------------------------------
I know how this works in Weld.
I am just saying that for observing the exception you would need to expect the exception coming from firing event, which itself seem pretty weird.
You can fire many other events which are outside of any transactions. So having the same call expecting a transaction error here looks out of place to me.
> Transactional observers fired in inconsistent manner when synchronisation cannot be placed
> ------------------------------------------------------------------------------------------
>
> Key: CDI-724
> URL: https://issues.jboss.org/browse/CDI-724
> Project: CDI Specification Issues
> Issue Type: Feature Request
> Affects Versions: 2.0 .Final
> Reporter: Jan-Willem Gmelig Meyling
> Priority: Major
>
> I have noticed some unexpected behaviour with the current workings of transactional observers. I have initially reported these issues under WELD-2444 , where [~mkouba] pointed out that WELD simply followed the CDI spec here:
> ??If the transaction is in progress, but javax.transaction.Synchronization callback cannot be registered due to the transaction being already marked for rollback or in state where javax.transaction.Synchronization callbacks cannot be registered, the before completion, after completion and after failure observer methods are notified at the same time as other observers, but after_success observer methods get skipped.??
> This choice has to some very unexpected side effects, namely:
> * If the synchronisation cannot be placed, AFTER_FAILURE observers will be invoked, even if the actual transaction already succeeded or is about to succeed. This may confuse users that expect the AFTER_FAILIURE observer to be invoked if and only if the actual transaction rolled back.
> * If the synchronisation cannot be placed, AFTER_FAILURE and AFTER_COMPLETION will be invoked immediately. This may confuse users that expect the actual transaction to be completed during the execution of the AFTER_FAILURE and AFTER_COMPLETION observers. Now, these observers may be invoked while still committing or rolling back.
> * If the synchronisation cannot be placed, the exception is swallowed silently (with the only mechanism to observe the failure being the unfortunate invocation of the AFTER_FAILURE observer). This may make it very difficult for someone trying to figure out why the AFTER_SUCCESS transactional observer was never invoked in the first place, even though the transaction did commit.
> In my opinion would be best to just throw an exception if the synchronisation cannot be placed, all of the above quirks will then be resolved. It also should be pretty easy to work around by just placing a single synchronisation, and queueing transactional observers in a transaction scoped queue.
> While at it: the issue originates from the fact that the synchronisation couldn't be added during the COMMITTING state. While I do understand this limitation, I think it might be worthwhile to consider to use an interposed (run last) synchronisation rather than plain transaction synchronisations. This would AFAIK also allow placing additional synchronisations while processing the existing synchronisations (except the interposed synchronisations that is). This can for example come in handy, when fireing events from JPA entity lifecycle listeners (which are typically invoked during FLUSH, which itself is triggered through a transaction synchronisation).
--
This message was sent by Atlassian Jira
(v7.12.1#712002)
6 years, 2 months
[JBoss JIRA] (CDI-724) Transactional observers fired in inconsistent manner when synchronisation cannot be placed
by Jan-Willem Gmelig Meyling (Jira)
[ https://issues.jboss.org/browse/CDI-724?page=com.atlassian.jira.plugin.sy... ]
Jan-Willem Gmelig Meyling commented on CDI-724:
-----------------------------------------------
[~manovotn] The exception is swallowed in https://github.com/weld/core/blob/master/modules/jta/src/main/java/org/jb... . So when a callee in TX state COMMITTING attempts to fire a transactional event, the synchronisation cant be added, exception will be swallowed, and the "after failure" observers will be invoked (even though the transaction is succesful).
> Transactional observers fired in inconsistent manner when synchronisation cannot be placed
> ------------------------------------------------------------------------------------------
>
> Key: CDI-724
> URL: https://issues.jboss.org/browse/CDI-724
> Project: CDI Specification Issues
> Issue Type: Feature Request
> Affects Versions: 2.0 .Final
> Reporter: Jan-Willem Gmelig Meyling
> Priority: Major
>
> I have noticed some unexpected behaviour with the current workings of transactional observers. I have initially reported these issues under WELD-2444 , where [~mkouba] pointed out that WELD simply followed the CDI spec here:
> ??If the transaction is in progress, but javax.transaction.Synchronization callback cannot be registered due to the transaction being already marked for rollback or in state where javax.transaction.Synchronization callbacks cannot be registered, the before completion, after completion and after failure observer methods are notified at the same time as other observers, but after_success observer methods get skipped.??
> This choice has to some very unexpected side effects, namely:
> * If the synchronisation cannot be placed, AFTER_FAILURE observers will be invoked, even if the actual transaction already succeeded or is about to succeed. This may confuse users that expect the AFTER_FAILIURE observer to be invoked if and only if the actual transaction rolled back.
> * If the synchronisation cannot be placed, AFTER_FAILURE and AFTER_COMPLETION will be invoked immediately. This may confuse users that expect the actual transaction to be completed during the execution of the AFTER_FAILURE and AFTER_COMPLETION observers. Now, these observers may be invoked while still committing or rolling back.
> * If the synchronisation cannot be placed, the exception is swallowed silently (with the only mechanism to observe the failure being the unfortunate invocation of the AFTER_FAILURE observer). This may make it very difficult for someone trying to figure out why the AFTER_SUCCESS transactional observer was never invoked in the first place, even though the transaction did commit.
> In my opinion would be best to just throw an exception if the synchronisation cannot be placed, all of the above quirks will then be resolved. It also should be pretty easy to work around by just placing a single synchronisation, and queueing transactional observers in a transaction scoped queue.
> While at it: the issue originates from the fact that the synchronisation couldn't be added during the COMMITTING state. While I do understand this limitation, I think it might be worthwhile to consider to use an interposed (run last) synchronisation rather than plain transaction synchronisations. This would AFAIK also allow placing additional synchronisations while processing the existing synchronisations (except the interposed synchronisations that is). This can for example come in handy, when fireing events from JPA entity lifecycle listeners (which are typically invoked during FLUSH, which itself is triggered through a transaction synchronisation).
--
This message was sent by Atlassian Jira
(v7.12.1#712002)
6 years, 2 months
[JBoss JIRA] (CDI-724) Transactional observers fired in inconsistent manner when synchronisation cannot be placed
by Matej Novotny (Jira)
[ https://issues.jboss.org/browse/CDI-724?page=com.atlassian.jira.plugin.sy... ]
Matej Novotny commented on CDI-724:
-----------------------------------
bq. In my opinion would be best to just throw an exception if the synchronisation cannot be placed,...
I cannot really see where would this exception be thrown and where would the user monitor it?
As for interposed synchronization - there is no way to know when CDI should register an interposed sync. and when it should register the ordinary one. Besides registering interposed carries additional risks; user logic may depend on certain resources which may or may now be available once you start executing interposed sync. callbacks.
bq. It also should be pretty easy to work around by just placing a single synchronisation, and queueing transactional observers in a transaction scoped queue.
This looks like a good way to approach it. If we do that, we need to remember to correct spec at [10.5. Observer notification|http://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#observer_no...] where we currently forbid it by saying:
??for each observer method, either invoke the observer method immediately, or register the observer method for later invocation during the transaction completion phase, using a JTA Synchronization.??
> Transactional observers fired in inconsistent manner when synchronisation cannot be placed
> ------------------------------------------------------------------------------------------
>
> Key: CDI-724
> URL: https://issues.jboss.org/browse/CDI-724
> Project: CDI Specification Issues
> Issue Type: Feature Request
> Affects Versions: 2.0 .Final
> Reporter: Jan-Willem Gmelig Meyling
> Priority: Major
>
> I have noticed some unexpected behaviour with the current workings of transactional observers. I have initially reported these issues under WELD-2444 , where [~mkouba] pointed out that WELD simply followed the CDI spec here:
> ??If the transaction is in progress, but javax.transaction.Synchronization callback cannot be registered due to the transaction being already marked for rollback or in state where javax.transaction.Synchronization callbacks cannot be registered, the before completion, after completion and after failure observer methods are notified at the same time as other observers, but after_success observer methods get skipped.??
> This choice has to some very unexpected side effects, namely:
> * If the synchronisation cannot be placed, AFTER_FAILURE observers will be invoked, even if the actual transaction already succeeded or is about to succeed. This may confuse users that expect the AFTER_FAILIURE observer to be invoked if and only if the actual transaction rolled back.
> * If the synchronisation cannot be placed, AFTER_FAILURE and AFTER_COMPLETION will be invoked immediately. This may confuse users that expect the actual transaction to be completed during the execution of the AFTER_FAILURE and AFTER_COMPLETION observers. Now, these observers may be invoked while still committing or rolling back.
> * If the synchronisation cannot be placed, the exception is swallowed silently (with the only mechanism to observe the failure being the unfortunate invocation of the AFTER_FAILURE observer). This may make it very difficult for someone trying to figure out why the AFTER_SUCCESS transactional observer was never invoked in the first place, even though the transaction did commit.
> In my opinion would be best to just throw an exception if the synchronisation cannot be placed, all of the above quirks will then be resolved. It also should be pretty easy to work around by just placing a single synchronisation, and queueing transactional observers in a transaction scoped queue.
> While at it: the issue originates from the fact that the synchronisation couldn't be added during the COMMITTING state. While I do understand this limitation, I think it might be worthwhile to consider to use an interposed (run last) synchronisation rather than plain transaction synchronisations. This would AFAIK also allow placing additional synchronisations while processing the existing synchronisations (except the interposed synchronisations that is). This can for example come in handy, when fireing events from JPA entity lifecycle listeners (which are typically invoked during FLUSH, which itself is triggered through a transaction synchronisation).
--
This message was sent by Atlassian Jira
(v7.12.1#712002)
6 years, 2 months