I'd like to know how to configure the location of ObjectStore for JTA. My target is Helidon MP. Currently directories named "ObjectStore" and "PutObjectStoreDirHere" are automatically created under the current directory. Also I'd like to make sure if we really need two directories in order to manage transactions.

3

There are 3 answers

2
Laird Nelson On

These directory names are the default names for certain directories provided by the Narayana transaction engine, which underlies Helidon's JTA support.

I am not a Narayana expert, but from looking at their source code, it appears that at a certain point they are going to construct an instance of ObjectStoreEnvironmentBean. As you can see, it has a getter method called getObjectStoreDir(). Ultimately this is going to give Narayana the name of the object store directory.

Now, how does this get populated? Again, from looking at the Narayana source code, it appears that this instance will be populated by way of something called a BeanPopulator. Specifically, the BeanPopulator will acquire a default set of properties, and then apply them to the bean under configuration—ObjectStoreEnvironmentBean in this case—and that will provide the name of the object store directory (among other things).

OK, fine, but where do these properties come from? It appears that the default set of properties is located (ultimately) by the AbstractPropertiesFactory class. Specifically, its initDefaultProperties method is going to look for an XML file of a particular kind and load it.

What kind of XML file will it look for? It looks like if there is a System property named com.arjuna.ats.arjuna.common.propertiesFile, that resolves to the path of the XML file in question, it will be used. If there is no such System property, then we can see that the return value from ConfigurationInfo#getPropertiesFile() is used instead.

Somewhat bizarrely, during the build of Narayana (!), that method's bytecode is replaced (!) with a recipe that comes from the pom.xml, and finally there we can see our answer: the return value of this method will be, exactly, jbossts-properties.xml.

That is, of course, a relative path of some kind, or perhaps a classpath resource. Which is it? For that, we have to return back to the AbstractPropertiesFactory class and note how that name is used. We can see that it is sought in various locations via the FileLocator#locateFile() method. The FileLocator#locateFile() method first tries to treat the name as an absolute path (clearly we can see that jbossts-properties.xml is not an absolute path), then as a path relative to the user.dir, user.home and java.home System properties in that order (almost certainly this will not exist either), and finally as a classpath resource. So there is our answer: jbossts-properties.xml, if present as a classpath resource, will be used as the source for where the object store directory should be created and located by Narayana.

Now, what does this XML file look like? It appears that an example file can be found here: https://github.com/jbosstm/narayana/blob/master/ArjunaJTA/narayana-jta/src/main/resources/jbossts-properties.xml. You can see that something like this is ultimately where PutObjectStoreDirHere comes from. So I think if you set one of these up in one of the locations detailed above you can get the object store put in whatever place you want.

Things get a little weird, though, because while this answers the question of where PutObjectStoreDirHere comes from, it does not seemingly answer the question of where, simply, ObjectStore comes from. We can see that this appears to be the default value of the objectStoreDir bean property if we look at the source code of ObjectStoreEnvironmentBean again, so my guess here is that there may be some other property involved.

As mentioned before, I'm not a Narayana expert, so it might be best to get in touch with the Narayana folks to find out all the details about all the edge cases here.

3
lscoughlin On

According to the Narayana documentation, you can set one of the following system properties.

  1. ObjectStoreEnvironmentBean.objectStoreDir
  2. ObjectStoreEnvironmentBean.localOSRoot

as in

java -DObjectStoreEnvironmentBean.objectStoreDir=/tmp/whatever -jar my-helidon-mp-thing-that-cant-tell-jpa-and-jta-apart.jar

But that only really moves the "PutObjectStoreDirHere" directory. The "ObjectStore" directory is hard coded in Narayana to this:

private volatile String objectStoreDir = System.getProperty("user.dir") + File.separator + "ObjectStore";

And there's no good way in helidon/CDI to plug into the initialization cycle and call ObjectStoreEnvironmentBean::setObjectStoreDir so, we just have to live with that.

The bigger question to me is, why do we have to have some noisy JTA implementation when really all anyone want's @Transaction to do is open and close a transaction. JTA is really not a value add here, or anywhere really.

0
westman379 On

You can set object store directory with this option passed to the application:

-Duser.dir=/object-store

But if there is any issue with the current object store (like file writing / permissions issues), I personally think that the better solution would be changing object store type to different type, e.g. volatile store that doesn't need to write to any files, you can do it with this option passed to the application:

-Dcom.arjuna.ats.arjuna.common.ObjectStoreEnvironmentBean.objectStoreType=com.arjuna.ats.internal.arjuna.objectstore.TwoPhaseVolatileStore

You can check available object stores in the narayana's source code https://github.com/jbosstm/narayana/blob/5.12.0.Final/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/objectstore/TwoPhaseVolatileStore.java