Is there any way to change the location of ObjectStore and PutObjectStoreDirHere when enabling JTA on Helidon MP? - helidon

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.

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.

According to the Narayana documentation, you can set one of the following system properties.
ObjectStoreEnvironmentBean.objectStoreDir
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.

Related

Environment Variable To Register Libraries From Custom Location (OCX, DLL)

I've searched far an wide for this specific problem, but I only find separate solutions for each problem individually. I basically want to know what the name of the environment variable should be. My assumption is that the name of the variable should be the name of the component and that it should be User variable and not System variable, for example:
name -> "mydll.dll"
path -> "c:\myCustomPath\mydll.dll"
The reason why I want to do this is because of two reasons. First, I often run my custom made tools either directly from the source code in a VM (which is sort of a pain), or I compile it and run it in W10. However, I just cannot do that with more complex apps that have dependencies because then I would have to register tons of DLLs onto the system root, and I know that I would lose track of it easily. The second reason is because I read this reply the guy says it's not recommended to use the system root for private libraries and he also suggests using an environment variable which sounded like a good solution to my problem.
The reason why I have not tested this myself through trial and error is because I'm afraid of leaving my only computer unusable if I put something wrong in the variable. Also all the libraries and exe files that I'm using are written and compiled in VB6, so I have no easy way around it since I already tried merging the multiple projects into one on a rather small project. I ended up rewriting almost the whole thing because VB6 doesn't like public types enums, etc in private Object Classes.
Finally, I am not sure if my question should be here since it doesn't involve programming, but I just felt it would be better understood here.
If I understand your question correctly, you are asking where you can place COM DLLs so that you can register them on your computer.
The answer is - fundamentally - that it does not matter where they are located because registration has a "global" effect. (Simplifying a little).
Now of course there are standards or conventions for where system-wide registered DLLs should go - e.g., Windows\SysWOW64 folder. But the point is that if you register the wrong thing, or leave out dependencies, or remove a registered DLL without unregistering it - etc. etc. - you will cause problems.
I am not aware of any environment variable that has anything to do with this basic function of COM DLLs. (I may be ignorant of something).
If you are actually using an application manifest (as maybe implied in the question) then you don't need to and should not register any DLL which is manifested.

Make IntelliJ aware of links to Java elements in XML files

I have a custom XML format that links to Java resources. For the sake of simplicity let's assume my XML file would look like this:
<root>
<java-class>my.fully.qualified.class.name</java-class>
</root>
Eventually my references will be somewhat more complicated. It will not contain the fully qualified class name directly and I will need some logic to resolve the correct class, but I want to keep the example as simple as possible here.
Now I want it to be possible to Strg+Click on the element's text and want IntelliJ to carry me to the .java file, just like it is possible in Spring-XML files. In the IDEA Plugin Development FAQ there is a link called "How do I add custom references to Java elements in XML files?" which so much sounds like exactly what I need. Unfortunately it links to a discussion where someone is more or less done implementing something like this, having some minor problems. Nevertheless I understood that I probably need to write an implementation of the interface com.intellij.psi.PsiReference. Googling for "PsiReference" and "IntelliJ" or "IDEA" unfortunately did not bring up any tutorials on how to use it, but I found the class XmlValueReference which sounds useful. Yet again googling for "XmlValueReference" did not turn up anything useful on how to use the class. At least the PSI Cookbook tells me that I can find the Java class by using JavaPsiFacade.findClass(). I'd be thankful for any tutorials, hints and the like, that tell the correct usage.
The above linked discussion mentions that I need to call registry.registerReferenceProvider(XmlTag.class, provider) in order to register my provider once I eventually managed to implement it, but of which type is "registry" and where do I get it from?
First of all, here's a nice tutorial that came up a few days ago, which explains the basics of IntelliJ plugin development (you should take a look at the section Reference Contributor).
You will likely have to define your own PsiReferenceContributor, which will be referenced in your plugin.xml like this:
<psi.referenceContributor implementation="com.yourplugin.YourReferenceContributor"/>
In your reference contributor, there's a method registerReferenceProviders(PsiReferenceRegistrar) where you will be able to call registry.registerReferenceProvider(XmlTag.class, provider).
Finally, in your instance of PsiReferenceProvider, you will have to test the tag name to filter out tags which don't contain class references, then find the right Java class using JavaPsiFacade.findClass().
From my experience, the best place to get help regarding IntelliJ plugin development is JetBrains' forums.

AspectJ & controlling calls in other jars

POST 1: theoretical question
We use some software, that is actually a Web Module with its own Tomcat and shell scripts for controlling it. It has also a Plugin System, which allows you to upload a .jar file with a certain structure to add new functionality to the Application.
Question:
I would like to control&actually change the responses to different calls in the main system/application (not in my jar). Could I use AspectJ to do that? Why or why not? What would be the other general possibilities, except changing the code of the Main Application.
POST 2: the try
I tried to do it this way (in Eclipse):
In the AspectJ Project I added the jar file, where the classes to be woven are (actually I added it to the INPATH).
Exported the Project as "Jar with AspectJ support"
Deployed the jar file exported at the step 2: No result.
Questions:
In the exported aspect-jar, there are only the .class files of the AspectJ project, no .class files for the INPATH-Jar.
Should there be other classes, from the imported INPATH-jar?
In the exported aspect-jar there is no jar with the aspectj-runtime (aspectj-rt.jar). Should it be there, or how to configure the virtual machine to have it?
Yes, why not? If you could extend your question and explain (maybe with an example) which actors and actions there are in the system, we might be able to help you in a more conrete fashion. But basically I see no problem. The JAR modules might be loaded dynamically, but if you know which calls in the Tomcat app you want to intercept, you can easily instrument them either statically by reweaving the existing classes or dynamically via LTW (load-time weaving) during JVM start-up. There is no need to touch your uploaded JAR modules, which is, as I understand you, what you want to avoid.
You probably want to weave your main application's target classes via
execution(<methodsToBeChecked>) pointcut in combination with
around() advice.
The other details depend on your specific use case, the package, class and method names, parameters etc. The around advice can do one or several of the following things:
determine caller,
check call paramaters,
manipulate call parameters,
call original target with original or changed parameters,
alternatively not perform the original call at all,
pass back the result of the original call to the caller,
pass back a manipulated version of the result to the caller,
pass any synthetic value with the correct return type to the caller,
catch exceptions raised by the original call,
throw your own exceptions
etc.
Your fantasy (and AspectJ's few limitations) are the limit. :-)

What does (filename.java.i, filename.jar.i) extension mean

I have files named xxx.java.i,xxx.java.d,xxx.jar.i. I know that these file are somehow related to Java. What does this extension mean and for what is it used? Is it same type as the .class extension?
You should look at your build system for more information. It is possible that these are intermediate files that get transformed and renamed to ".java". For example, I've seen various build systems that use the ".i" suffix to mean "input", and perform various forms of variable substitution (e.g. changing something like "{VERSION_NUMBER}" to the version number of the library being compiled).
I think they are created by someone to serve his own purpose and unless we ask the author or see the content we won't know what it the purpose is.
If you see garbled characters, it's probably java bytecode and you can use some decompiler to see the code (see: How do I "decompile" Java class files?).

using my own config file in my application

As a practice exercise at my college we have to make a simple room booking system, complete with its own config file. We're not allowed to use the one built into VB.NET (the professor wants us to adapt to not relying on things like that) so I've made my own. This is a sample:
// Config file.
// First column is the variable name that will be used to
// reference the value in the second column. Seperate each
// setting with a new line.
MasterUser Chris
DatabasePath C:\Users\Chris\Desktop\Project.mdb
Comments in the file are pretty self-explanatory. I can parse the file fine, but what I'm having trouble with is making a variable the same name as whats in the first column. For example I need to make a variable called MasterUser and one called DatabasePath that holds Chris and C:\Users\Chris\Desktop\Project.mdb as values respectively. But I have no idea how to make a variable called that.
Any help would be cool, thanks. :)
EDIT: You can't see it from the code view here, but the variable name and value in the config file are separated by a tab :)
You might want to consider using a better format for your configuration file, like XML. This will give you a lot more library support for parsing and searching within the file... that said, in this simple case, it looks like you just need a simple Dictionary(Of String, String) which probably won't make a lot of sense if you haven't learned about Generics yet :)
Basically you can load values in like this:
Dim settings As New Dictionary(Of String, String)
settings.Add("MasterUser", "Chris")
settings.Add("DatabasePath", "C:\Users\Chris\Desktop\Project.mdb")
Then when you want to retrieve a value based on the key in the dictionary, you can do it like this:
Dim master As String = settings("MasterUser") ' master = "Chris"
I hope that helps clear things up.
Well, in the strict sense, you cannot "Make a variable named from file data" in most compiled languages. What you could do is to make a name-value association set (that's a Dictionary in .Net) and add entries to it based on what you read from a file.
However, what most programmers do is to "invert" that logic: as you code reads each line, it just does a series of IF's on the Name to see if it is recognized, and if so then just assings it to the corresponding predefined variable of the same name.
There are formats & libraries specially made for this (like XML, that's why the built in configs use it), but that might still be the kind of thing that you are not supposed to rely on.
Since your configuration file is not compiled into your code in any meaningful way, you aren't going to be able to create a variable (that is, a strongly-typed property or field on a class) dynamically. You have a couple of options.
If you want to keep your configuration file format:
Create a class that contains all possible configuration keys as properties. Give that class a Load() method that knows how to parse a file into the class.
Use a Dictionary -- either the Generics version or good old fashioned System.Collections.Dictionary. You'll retrieve elements with string keys.
If you're willing to change your configuration file format to XML, then you can use Serialization. This frees you from having to maintain a parser, but it requires a little bit more setup.
See here for my answer to another SO's question using nini and where to download it from. Essentially nini is a simple INI read/write library for configuration files. The question that remains to be seen is will your professor allow this inclusion of 3rd party open source?
Hope this helps,
Best regards,
Tom.