[JBoss JIRA] (ISPN-7505) Non-functional read in transaction with modifications returns old value
by Pedro Ruivo (JIRA)
[ https://issues.jboss.org/browse/ISPN-7505?page=com.atlassian.jira.plugin.... ]
Pedro Ruivo updated ISPN-7505:
------------------------------
Status: Resolved (was: Pull Request Sent)
Fix Version/s: 9.0.0.CR3
Resolution: Done
> Non-functional read in transaction with modifications returns old value
> -----------------------------------------------------------------------
>
> Key: ISPN-7505
> URL: https://issues.jboss.org/browse/ISPN-7505
> Project: Infinispan
> Issue Type: Bug
> Components: Core
> Affects Versions: 9.0.0.CR1
> Reporter: Radim Vansa
> Assignee: Radim Vansa
> Fix For: 9.0.0.CR3
>
>
> See this modified FunctionalTxInMemoryTest:
> {code:java}
> @Test(dataProvider = "owningModeAndReadWrites")
> public void testReadWriteAfterMods(boolean isOwner, WriteMethod method) throws Exception {
> Object KEY = getKey(isOwner);
> cache(0, DIST).put(KEY, "a");
> tm.begin();
> assertEquals("a", rw.eval(KEY, append("b")).join());
> assertEquals("ab", rw.evalMany(Collections.singleton(KEY), append("c")).findAny().get());
> assertEquals("abc", cache(0, DIST).get(KEY)); // <-- THIS FAILS
> assertEquals(null, rw.eval("otherKey", append("d")).join());
> assertEquals("abc", method.action.eval(KEY, wo, rw,
> MarshallableFunctions.returnReadOnlyFindOrNull(),
> (BiConsumer<EntryView.WriteEntryView<String>, String> & Serializable) (e, prev) -> {}, getClass()));
> tm.commit();
> }
> {code}
> When the entry was modified in given transaction, we have to do the read using functional identity read which passes all modifications along. We need to do this for all {{remoteGet}} s, including those invoked for {{putIfAbsent}} etc.
--
This message was sent by Atlassian JIRA
(v7.2.3#72005)
7 years, 10 months
[JBoss JIRA] (ISPN-7550) Remove TriangleAckInterceptor
by Gustavo Fernandes (JIRA)
[ https://issues.jboss.org/browse/ISPN-7550?page=com.atlassian.jira.plugin.... ]
Gustavo Fernandes updated ISPN-7550:
------------------------------------
Status: Resolved (was: Pull Request Sent)
Resolution: Done
> Remove TriangleAckInterceptor
> -----------------------------
>
> Key: ISPN-7550
> URL: https://issues.jboss.org/browse/ISPN-7550
> Project: Infinispan
> Issue Type: Bug
> Components: Core
> Reporter: Pedro Ruivo
> Assignee: Pedro Ruivo
> Fix For: 9.0.0.CR3
>
>
> {{TriangleAckInterceptor}} has 2 main goals
> 1. sends the from backup/primary to originator
> 2. in originator, waits for the acks
> ... and has 2 issues:
> 1. if an exception occurs before it, the ack will not be sent!
> 2. waiting for the acks here will add more complexity to the following interceptor if they need the operation outcome.
> So, by removing the interceptor will have:
> 1. acks are sent in inbound handler (where the replies are sent too)
> 2. waiting for ack will happen on {{TriangleDistributionInterceptor}}.
> Other changes:
> * before sending the ack, notify the {{TriangleOrderManager}} that the next command can proceed.
--
This message was sent by Atlassian JIRA
(v7.2.3#72005)
7 years, 10 months
[JBoss JIRA] (ISPN-7550) Remove TriangleAckInterceptor
by Gustavo Fernandes (JIRA)
[ https://issues.jboss.org/browse/ISPN-7550?page=com.atlassian.jira.plugin.... ]
Gustavo Fernandes updated ISPN-7550:
------------------------------------
Fix Version/s: 9.0.0.CR3
(was: 9.0.0.Final)
> Remove TriangleAckInterceptor
> -----------------------------
>
> Key: ISPN-7550
> URL: https://issues.jboss.org/browse/ISPN-7550
> Project: Infinispan
> Issue Type: Bug
> Components: Core
> Reporter: Pedro Ruivo
> Assignee: Pedro Ruivo
> Fix For: 9.0.0.CR3
>
>
> {{TriangleAckInterceptor}} has 2 main goals
> 1. sends the from backup/primary to originator
> 2. in originator, waits for the acks
> ... and has 2 issues:
> 1. if an exception occurs before it, the ack will not be sent!
> 2. waiting for the acks here will add more complexity to the following interceptor if they need the operation outcome.
> So, by removing the interceptor will have:
> 1. acks are sent in inbound handler (where the replies are sent too)
> 2. waiting for ack will happen on {{TriangleDistributionInterceptor}}.
> Other changes:
> * before sending the ack, notify the {{TriangleOrderManager}} that the next command can proceed.
--
This message was sent by Atlassian JIRA
(v7.2.3#72005)
7 years, 10 months
[JBoss JIRA] (ISPN-7541) Health DMR fails with NPE in domain mode
by Ryan Emerson (JIRA)
[ https://issues.jboss.org/browse/ISPN-7541?page=com.atlassian.jira.plugin.... ]
Ryan Emerson resolved ISPN-7541.
--------------------------------
Fix Version/s: 9.0.0.CR3
Resolution: Done
> Health DMR fails with NPE in domain mode
> ----------------------------------------
>
> Key: ISPN-7541
> URL: https://issues.jboss.org/browse/ISPN-7541
> Project: Infinispan
> Issue Type: Bug
> Components: JMX, reporting and management, Server
> Reporter: Ryan Emerson
> Assignee: Sebastian Łaskawiec
> Fix For: 9.0.0.CR3
>
>
> Server error when trying to access the HEALTH in domain mode:
> {code:java}
> [Host Controller] 10:21:09,122 ERROR [org.jboss.as.controller.management-operation] (management-handler-thread - 25) WFLYCTL0013: Operation ("read-attribute") failed - address: ([
> [Host Controller] ("profile" => "clustered"),
> [Host Controller] ("subsystem" => "datagrid-infinispan"),
> [Host Controller] ("cache-container" => "clustered"),
> [Host Controller] ("health" => "HEALTH")
> [Host Controller] ]): java.lang.NullPointerException
> [Host Controller] at org.jboss.as.clustering.infinispan.subsystem.HealthMetricsHandler.executeRuntimeStep(HealthMetricsHandler.java:106)
> [Host Controller] at org.jboss.as.controller.AbstractRuntimeOnlyHandler$1.execute(AbstractRuntimeOnlyHandler.java:53)
> [Host Controller] at org.jboss.as.controller.AbstractOperationContext.executeStep(AbstractOperationContext.java:890)
> [Host Controller] at org.jboss.as.controller.AbstractOperationContext.processStages(AbstractOperationContext.java:659)
> [Host Controller] at org.jboss.as.controller.AbstractOperationContext.executeOperation(AbstractOperationContext.java:370)
> [Host Controller] at org.jboss.as.controller.OperationContextImpl.executeOperation(OperationContextImpl.java:1329)
> [Host Controller] at org.jboss.as.controller.ModelControllerImpl.internalExecute(ModelControllerImpl.java:400)
> [Host Controller] at org.jboss.as.controller.ModelControllerImpl.execute(ModelControllerImpl.java:222)
> [Host Controller] at org.jboss.as.controller.remote.ModelControllerClientOperationHandler$ExecuteRequestHandler.doExecute(ModelControllerClientOperationHandler.java:208)
> [Host Controller] at org.jboss.as.controller.remote.ModelControllerClientOperationHandler$ExecuteRequestHandler.access$300(ModelControllerClientOperationHandler.java:130)
> [Host Controller] at org.jboss.as.controller.remote.ModelControllerClientOperationHandler$ExecuteRequestHandler$1$1.run(ModelControllerClientOperationHandler.java:152)
> [Host Controller] at org.jboss.as.controller.remote.ModelControllerClientOperationHandler$ExecuteRequestHandler$1$1.run(ModelControllerClientOperationHandler.java:148)
> [Host Controller] at java.security.AccessController.doPrivileged(Native Method)
> [Host Controller] at javax.security.auth.Subject.doAs(Subject.java:422)
> [Host Controller] at org.jboss.as.controller.AccessAuditContext.doAs(AccessAuditContext.java:149)
> [Host Controller] at org.jboss.as.controller.remote.ModelControllerClientOperationHandler$ExecuteRequestHandler$1.execute(ModelControllerClientOperationHandler.java:148)
> [Host Controller] at org.jboss.as.protocol.mgmt.AbstractMessageHandler$ManagementRequestContextImpl$1.doExecute(AbstractMessageHandler.java:363)
> [Host Controller] at org.jboss.as.protocol.mgmt.AbstractMessageHandler$AsyncTaskRunner.run(AbstractMessageHandler.java:472)
> [Host Controller] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
> [Host Controller] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
> [Host Controller] at java.lang.Thread.run(Thread.java:745)
> [Host Controller] at org.jboss.threads.JBossThread.run(JBossThread.java:320)
> {code}
--
This message was sent by Atlassian JIRA
(v7.2.3#72005)
7 years, 10 months
[JBoss JIRA] (ISPN-7572) Infinispan initialization via DirectoryProvider can't use any CacheStore or other extensions
by Sanne Grinovero (JIRA)
[ https://issues.jboss.org/browse/ISPN-7572?page=com.atlassian.jira.plugin.... ]
Sanne Grinovero commented on ISPN-7572:
---------------------------------------
IRC transcript:
{noformat}
[20:30] <sannegrinovero_> ttarrant: I'm not sure how to help here: http://stackoverflow.com/questions/42655995/infinispan-wildfly-cannot-fin...
[20:30] <sannegrinovero_> any ideas?
[20:30] <sannegrinovero_> maybe we can improve error message to give some more hints?
[20:40] <sannegrinovero_> ttarrant: shouldn't infinispan core module depend on org.infinispan.persistence.jdbc ?
[20:41] <sannegrinovero_> I don't understand how it can find the extension..
[20:41] <ttarrant> sannegrinovero_, he should be using 8.1
[20:41] <sannegrinovero_> (it doesn't depend on it)
[20:41] <sannegrinovero_> yes I checked out 8.1
[20:42] <sannegrinovero_> ah no sorry I was checking 8.2.6 to be exact
[20:43] <ttarrant> sannegrinovero_, I mean he's using the core 8.1 namespace and jdbc 8.0 namespace
[20:43] <ttarrant> sannegrinovero_, he could skip using namespaces altogether actually. The parsers work in the default namespace too.
[20:44] <ttarrant> sannegrinovero_, our integration tests actually use programmatic config
[20:44] <sannegrinovero_> ttarrant: ic, slight namespace mismatch.. shouldn't fail for that?
[20:45] <sannegrinovero_> ttarrant: but mainly I'd like to understand how Infinispan can find its extensions since it doesn't depend on the org.infinispan.persistence.jdbc module
[20:47] <ttarrant> sannegrinovero_, let me add a test
[21:00] <jbossbot> new jira [ISPN-7571] Add a JDBC declarative test to the wildfly module integration tests [New (Unresolved) Task, Major, WildFly modules, Tristan Tarrant] https://issues.jboss.org/browse/ISPN-7571
[21:02] <ttarrant> sannegrinovero_, https://github.com/infinispan/infinispan/pull/4944/files
[21:02] <jbossbot> git pull req [infinispan] (open) Tristan Tarrant ISPN-7571 Add a declarative JDBC config IT to the wildfly modules https://github.com/infinispan/infinispan/pull/4944
[21:02] <jbossbot> jira [ISPN-7571] Add a JDBC declarative test to the wildfly module integration tests [Pull Request Sent (Unresolved) Task, Major, WildFly modules, Tristan Tarrant] https://issues.jboss.org/browse/ISPN-7571
[21:04] <ttarrant> sannegrinovero_, the default ParserRegistry uses the TCCL to find services
[21:07] <ttarrant> sannegrinovero_, otherwise you would need to alter the core module to depend on any services you need, and that is not how the services stuff should work
[21:09] <sannegrinovero_> ttarrant: mmm one can't always use the TCCL :(
[21:09] <ttarrant> sannegrinovero_, and one cannot always alter a module to add things to the classpath
[21:09] <sannegrinovero_> ttarrant: remember we had to override the TCCL in several integrations to avoid classpath isolation issues?
[21:10] <ttarrant> sannegrinovero_, you forget I lived inside the server for a long time. I know those things well
[21:10] <sannegrinovero_> ttarrant: ok so you know it's wrong? :)
[21:10] <ttarrant> sannegrinovero_, the ParserRegistry also supports supplying your own classloader
[21:11] <sannegrinovero_> ttarrant: in the H.Search case, the TCCL contains WildFly's Infinispan "main", I can't provide that one..
[21:12] <sannegrinovero_> ttarrant: https://github.com/infinispan/infinispan/blob/master/lucene/directory-pro...
[21:14] <ttarrant> sannegrinovero_, https://github.com/infinispan/infinispan/blob/master/lucene/directory-pro...
[21:14] <ttarrant> sannegrinovero_, looks wrong to me
[21:14] <ttarrant> sannegrinovero_, and that is why you have to do that silly TCCL trick further down
[21:14] <sannegrinovero_> ttarrant: well that was agreed a long time ago, pretty much the only thing I can to do workaround a dozen of other problems..
[21:15] <ttarrant> sannegrinovero_, if you had passed the correct classloader to the parserregistry you wouldn't need to do that
[21:15] <ttarrant> sannegrinovero_, and that is generally the classloader of the user code
[21:15] <ttarrant> sannegrinovero_, as that will have visibility over all the modules
[21:16] <sannegrinovero_> ttarrant: I think we disagree on the notion of "correct classloader": as I mentioned, passing in the application's classloader is a no-go for a ton of reasons
[21:16] <ttarrant> sannegrinovero_, so how do you expect the service loader pattern to work ?
[21:17] <sannegrinovero_> ttarrant: exactly! the infinispan-core module needs to import services from its extensions, like the jdbc-cachestore module
[21:17] <ttarrant> sannegrinovero_, of course not
[21:17] <ttarrant> sannegrinovero_, adding a custom extension would require modifying the module deps
[21:17] <sannegrinovero_> that's custom extension. we're not talking about the custom ones here
[21:18] <ttarrant> sannegrinovero_, we treat anything that is not the file store as an extension
[21:18] <sannegrinovero_> ttarrant: yes I understand. Do I have to remind you that any app using JPA gets WildFly's Infinispan on classpath?
[21:19] <ttarrant> sannegrinovero_, and that is a mistake of the JPA module
[21:20] <sannegrinovero_> ttarrant: sure, I would agree with that. Except that you say it's JPA's module fault just because they do exactly the same: look for 2LC extensions from app classpath
[21:21] <sannegrinovero_> ttarrant: this is one of those cases which have been discussed over and over on the mailing lists. The agreed solution was to implement the workaround which you see in that code I linked to..
[21:22] <sannegrinovero_> ttarrant: in this case I don't need to allow random extensions but it would be nice to at least have the supported CacheStores. It's easily resolved by adding the (optional) dependency from the infinispan-core module.
[21:23] <ttarrant> no
[21:23] <sannegrinovero_> I can't solve it then?
[21:23] <ttarrant> sannegrinovero_, allow the user to pass his own classloader
[21:24] <ttarrant> sannegrinovero_, and pass that down to the ParserRegistry
[21:24] <sannegrinovero_> how does the user get a reference to "the right classloader" ?
[21:24] <sannegrinovero_> (and who is the user? this is JPA bootstrap..)
[21:25] <sannegrinovero_> remember the "user" is *required* to NOT have visibility on Infinispan modules..
[21:26] <ttarrant> sannegrinovero_, sure, but you're not really solving the problem
[21:27] <ttarrant> sannegrinovero_, you are just creating a hardcoded (albeit optional) dependency on a module which works around this problem but doesn't solve extensibility correctly
[21:29] <sannegrinovero_> ttarrant: I'm aware the modules system is limited.. welcome to my world :) But be aware that Jigsaw is even more limited.
[21:29] <ttarrant> sannegrinovero_, we need a way for modules which need to consume services to declare the types they can load
[21:29] <sannegrinovero_> ttarrant: still, it's the only viable solution which isn't rolling it all in a flat classloader
[21:29] <ttarrant> sannegrinovero_, so that modules which export those types can be made available dynamically
[21:30] <sannegrinovero_> yes but that would require bi-directionality you agree ttarrant?
[21:30] <ttarrant> sannegrinovero_, so the solution is......
[21:30] <ttarrant> sannegrinovero_, OSGi
[21:30] <sannegrinovero_> you'd need to be able to define " I can provide implementations for service X to module Y" ..
[21:30] <ttarrant> sannegrinovero_, not quite like that. Just the X bit
[21:31] <ttarrant> sannegrinovero_, it is up to Y to say "make me find all providers of X"
[21:31] <sannegrinovero_> well no you'd be screwed ttarrant as then you'd be providing a CacheSTore implementation for all Infinispan versions within WildFly ..
[21:32] <ttarrant> sannegrinovero_, service X would need a version qualifier
[21:32] <ttarrant> sannegrinovero_, I think jigsaw has that
[21:32] <sannegrinovero_> ttarrant: right, and we have neither such a qualifier nor bi-directionality .. so I think we're on the same page that I can't do better?
[21:32] <sannegrinovero_> ttarrant: no jigsaw doesn't have neither versions nor slots
[21:33] <ttarrant> sannegrinovero_, how does JPA find user classes: does it use TCCL ?
[21:34] <sannegrinovero_> ttarrant: close. It looks in the same classloader as were the /META-INF/persistence.xml is defined
[21:34] <sannegrinovero_> or if you list FQCN then yes you can extend that to TCCL
[21:35] <sannegrinovero_> dmlloyd: we're having a big debate on module systems ^ maybe you'll want to have some fun :)
[21:37] <sannegrinovero_> ttarrant: let's try to recap the requirements: we don't want any Infinispan version on the user's TCCL as this is internal stuff. Agree on that so far?
[21:37] <dmlloyd> sannegrinovero_: OK :)
[21:37] <ttarrant> sannegrinovero_, yes
[21:38] <sannegrinovero_> ttarrant: ok so the Infinispan "extensions" are also not on TCCL.. right? So I have to load Infinispan - which luckily I have the classloader of as I declare a dependency to it via the module.xml ..
[21:38] <ttarrant> sannegrinovero_, I think a solution is a meta module
[21:39] <sannegrinovero_> ttarrant: so I can bootstrap Infinispan, and I can override (temporarily) the TCCL so to "nudge" it to the right services.. but I need to be able to refer to these.
[21:39] <ttarrant> sannegrinovero_, which aggregates all infinispan modules together
[21:39] <ttarrant> sannegrinovero_, akin to the uber jar, but modular
[21:39] <sannegrinovero_> ttarrant: maybe, but just declaring an optional dependency from infinispan-core -> all extensions would be totally fine IMO
[21:40] <ttarrant> sannegrinovero_, I still disagree
[21:41] <ttarrant> sannegrinovero_, it is a workaround
[21:41] <dmlloyd> there is usually no 100% right answer in these situations: for a given service-based API, if you use TCCL, you allow many impls but the application has to "know" about it; if you use your own CL, you are restricted to a single impl at run time but you also do not have to expose impl dependencies to the user application
[21:41] <dmlloyd> in Jigsaw I proposed that there should be a way to load resources transitively and know what class loader each resource came from, so that you can have services that come from class loaders that you can't actually "see" otherwise
[21:41] <dmlloyd> but, that was shot down (of course - too useful!)
[21:41] <sannegrinovero_> ttarrant: I don't see why it is a workaround. Those extensions are useless anyway, if you want to "hide" them from your infinispan-core module.
[21:43] <dmlloyd> we often use both approaches in wildfly: for things (like XNIO) where you generally do not want many impls, we use the self-classloader; for things like JAXP where users like to have their own (for some reason), we use TCCL (but then often fall back to the self classloader approach)
[21:43] <ttarrant> sannegrinovero_, it is a workaround, because you are creating a forward dependency
[21:43] <dmlloyd> hope that helps :)
[21:44] <sannegrinovero_> dmlloyd: yes thanks. It's very much a pragmatic choice between hiding internal components, vs allowing end user's extensions
[21:44] <sannegrinovero_> ttarrant: again why do you even ship these modules if you don't want Infinispan to be able to see them?
[21:44] <dmlloyd> FWIW I think it's perfectly sensible to do both, in cases where you want the user to extend but you also want to hide your impl
[21:46] <ttarrant> sannegrinovero_, Infinispan does see them when you instantiate it directly from the user code. It is the pesky sub-provider (Infinispan directory) of a sub-provider (Hibernate Search) of JPA that is a problem
[21:46] <sannegrinovero_> ttarrant: you're essentially asking me to have to change the Hibernate Search module depending on the Infinispan configuration.. ?!
[21:47] <ttarrant> sannegrinovero_, not very much different from what you're asking me
[21:48] <sannegrinovero_> ttarrant: how is that sensible, when you can't even parse the configuration file "ISPN000327: Cannot find a parser for element 'string-keyed-jdbc-store' in na" .. if you don't have the extension
[21:48] <sannegrinovero_> clearly the extension needs to be a static dependency, so that we can parse..
[21:54] <ttarrant> sannegrinovero_, but then you have only fixed it for JDBC. What if I want to use another store
[21:55] <sannegrinovero_> ttarrant: I think we need to differentiate between "internal usage" i.e. when we hide Infinispan from user code vs explicit usage
[21:56] <sannegrinovero_> explicit usage is for power users, who optionally ship their own extensions .. and clearly for those to work they'll need Infinispan on their classpath
[21:56] <sannegrinovero_> but all users which don't have Infinispan on their classpath.. they won't have extensions either.
[21:57] <sannegrinovero_> we still ask them to configure it though, optionally using a CacheStore.
[21:57] <sannegrinovero_> ttarrant: the better solution is the "Infinispan boostrap app" which registers the CacheManager in JNDI .. rings a bell? I have been suggesting the need for that for long.
[21:58] <sannegrinovero_> That would solve it as it would be a different app, so it can extend whatever it wants,
[21:58] <sannegrinovero_> while the Cache using app could be isolated from it.
[21:58] <sannegrinovero_> Clearly deploying an Infinispan extension when not having visibility on Infinispan-core is a legit error..
{noformat}
> Infinispan initialization via DirectoryProvider can't use any CacheStore or other extensions
> --------------------------------------------------------------------------------------------
>
> Key: ISPN-7572
> URL: https://issues.jboss.org/browse/ISPN-7572
> Project: Infinispan
> Issue Type: Bug
> Components: Loaders and Stores, Lucene Directory, WildFly modules
> Affects Versions: 9.0.0.CR2, 8.2.6.Final
> Reporter: Sanne Grinovero
> Assignee: Tristan Tarrant
> Priority: Critical
> Fix For: 9.0.0.Final, 8.2.7.Final
>
>
> When the Infinispan CacheManager is bootstrapped via Hibernate Search, the Infinispan modules are not necessarily visible to the deployment classpath (the TCCL).
> In this case if the configuration file refers to any extension such as a {{CacheStore}}, Infinispan will fail to start as it doesn't depend on the modules of its extensions.
> This will cause puzzling errors such as :
> {{ISPN000327: Cannot find a parser for element 'string-keyed-jdbc-store' in namespace 'urn:infinispan:config:store:jdbc:8.0'. Check that your configuration is up-to date for this version of Infinispan.}}
> For the record, the fact that the configuration parser expects to use the TCCL is an old problem which I've highlighted already in the past:
> Explicit classloader support during parsing was introduced in 2013:
> - http://lists.jboss.org/pipermail/infinispan-dev/2013-April/012590.html
> Then removed again in 2014:
> - http://lists.jboss.org/pipermail/infinispan-dev/2014-May/014952.html
> I asked for improvements and hoped for someone to take ownership:
> - http://lists.jboss.org/pipermail/infinispan-dev/2014-October/015549.html
> In this last email I explained what Hibernate Search would do, in lack of better alternatives..and so we did.
> Finally, this component of Hibernate Search code was transferred to the Infinispan repository so luckily we can change both components as you see most fit; the only requirement is to not expect the Hibernate users to have Infinispan on their TCCL.
> My proposal is simple: the Infinispan-core module should have an optional dependency to its extensions, including at least all supported CacheStore implementations so that people can use them.
> In fact, I expected them to do as it feels natural to have a graph edge towards extension points to be able to load them.
> But [~NadirX] doesn't like that, so assigning the issue to him ;-)
> Alternative ideas:
> * allow people to mention module names explicitly in the Infinispan configuration?
> * have a module which bootstraps the CacheManager, depending explicitly on all extensions, and register it over JNDI
> I favour the second option, especially as it came up before as a dire pratical need for many other situations.
--
This message was sent by Atlassian JIRA
(v7.2.3#72005)
7 years, 10 months