Java resource clean up before object destruction - java

I've the following problem and I know there are already a lot of questions but none of these give me really a satisfactorily answer! I wrote a lot of stuff in C++ and this language provide a destructor, Java doesn't because of the garbage collection.
A little introduction in my situation: I wrote a software which is accessing a local Sqlite3 database. I wrote a central singleton class for accessing this database. Multiple other classes access the DB through this wrapper class. Here is the pseudo-code of this wrapper class:
public class MyDbWrapper
{
private currentDbConnection;
public MyDbWrapper(dbPath)
{
// Open the database connection with given path
}
public readFromDb()
{
... // Uses the class member currentDbConnection
}
public writeToDb()
{
... // Uses the class member currentDbConnection
}
public closeDb()
{
...
}
}
Now my question is, how could I ensure that the database connection is closed before quitting the application? Yes I already implemented the AutoCloseable interface and yes I worked already a lot with try-with-resources, but because of the access by multiple classes this isn't really an option!
In C++ a destructor would solve this issue, but the possible "equivalent" in java the method finalize is deprecated!
So are there any other options or should I totally re-design my complete wrapper? If yes, how could I prevent performance issues because of a lot of read write access if I re-open the database every time?

Like Joker_vD already said, I solved this issue by using a try-with-resources statement in the main method of my program...
public static void main(String [] args)
{
try(MyDbWrapper wrapper = new MyDbWrapper())
{
// Execute other task with usage of the database wrapper
}
}
With this solution there is no need for a desturctor or the usage of the deprecated method finalize(), the database connection get closed if program ends...
Thanks again and credits to Joker_vD

Related

How can I access COM automation DLLs from Java?

I have a third party application which includes a suite of DLL libraries that provide access to the application's data and commands.
Using Java, I want to access these DLLs in order to retrieve some specific data and write it to a file.
While similar questions to this have been asked before, I haven't found any that have helped me (I'm an absolute beginner at Java). I suspect this can be done with
JNA but need some guidance. It might be beyond my novice ability but I want to try.
There are several DLL files I need to access, each of which contain multiple libraries, which provide access to objects offering various functionality.
I need to gain access to these DLLs, instantiate objects from them, and gain access to the methods and variables provided. Is there a relatively easy Java solution that anyone knows of?
Thanks
EDIT: I've added example J++ code illustrating what I need to do in Java. J++ would firstly require creating COM wrappers for each of the required DLL files.
import dll1.*;
import dll2.*;
import dll3.*;
import com.ms.com.*;
public class Class1 {
public static void main(String[] args) {
// Create an application object
dll3.Application app = new dll3.Application();
// Use the getDataManager() method on the application
// object to get the DataManager object (which in turn is
// used to create the price object)
DataManager dm;
try {
dm = app.getDataManager();
} catch (Exception e) {
System.out.println(e);
return;
}
// Create the price data object using the CreateOb method of the
// DataManager object
PriceOb dp = (PriceOb) dm.CreateOb("Price");
// Set the requests parameters and make the request
dp.setVar1("abc");
dp.setVar2("xyz");
dp.Request();

Proper Vertx database etiquette

I'm fairly new to Vertx, And trying to find some realistic examples of database usage.
I have a Verticle that creates a shared database object (And a number of classes that handle routing, but I would like to use the shared database outside the main class, obviously I could pass the database object in other classes constructors, but I'm sure Vertx has some better way to do this.
public void start() {
...
this.postgreSQLClient = PostgreSQLClient.createShared(vertx, sqlClientConfig);
...
}
Does anyone have any Java Vertx examples with realistic implementations of a database?
Thank you in advance.
Use Dependency Injection. I have used Guice
Here's the example of it:
Main.java
//within main function where you have object of vertx
Guice.createInjector(new AppInjector(vertx));
AppInjector.java
//Create an Injector file and bind your injections
PostgreSQLClient postgreSQLClient = PostgreSQLClient.createShared(vertx, sqlClientConfig, "my-shared-client");
bind(PostgreSQLClient.class).annotatedWith(Names.named("DBClient")).toInstance(postgreSQLClient);
UserService.java
public class UserService {
#Inject
#Named("DBClient")
private PostgreSQLClient client;
}
You can find the source code here
Just specify a pool name:
if different clients are created using the same Vert.x instance and
specifying the same pool name, they will share the same data source.
So updating your example:
public void start() {
this.postgreSQLClient = PostgreSQLClient.createShared(vertx, sqlClientConfig, "my-shared-client");
}
Note that when doing this, the configuration provided in the first call will be used. Subsequent calls will simply return the existing client.

Use bolt driver and Java API of Neo4j simultaneously

Hello everybody!
I have developed a JavaFX application to support my scientific work (molecular biology/neuropharmacology), implementing Neo4j, at the time Version 2.x.
Now, since Version 3 (using 3.1.0-M05) is out, I am switching over to Bolt protocol access of the Database, with the Driver (1.1.0-M01) interface. Some functions of my application still require Java API access though, so I cannot completely abandon the old code. I am using a singleton GraphDatabaseFactory to start up the database, like so
private static GraphDatabaseService instance;
private GraphDb() {
instance = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(new File(FilePaths.DATABASE_PATH))
.setConfig(ShellSettings.remote_shell_enabled, "true").newGraphDatabase();
}
public static synchronized GraphDatabaseService getInstance() {
return instance;
}
(Or, just the .newEmbeddedDatabase())But now, since Version 3, I also use a singleton Driver instance for the Bolt interaction, like so
private static Driver instance;
private GraphDbDriver() {
startLocalDb();
instance = GraphDatabase.driver("bolt://localhost");
}
private static void startLocalDb() {
//start database here?
}
public static synchronized Driver getInstance() {
return instance;
}
My question now, is this (since I gathered that using both at the same time can only breed complications): How do I use these two ways of communicating with the DB without them getting in the way of each other?
Can I somehow get the Driver to load "onto" the already created GraphDatabaseService singleton?
Thanks for reading!
So, for anybody who's interested, in Neo4j 3.x it is recommended to use 'User-defined procedures' to implement API commands (like, e.g., traversals) and then calling it (via CALL) from cypher.

JNA calling CoInitialize when loading a dll

I've got a dll written in Pascal. I've determined that I need to run CoInitialize in the Java code, but I just can't figure out how.
I found another Stack Overflow thread which should have helped here: https://stackoverflow.com/questions/15763993 but I couldn't understand how it actually worked.
My current code that I have now is here:
public interface CSQLLib extends StdCallLibrary {
CSQLLib INSTANCE = (CSQLLib) Native.loadLibrary("DatabaseLibrary", CSQLLib.class);
public HRESULT CoInitialize(Pointer p);
public HRESULT CoUninitialize();
public String doSQLQuery(String input);
public void DllMessage();
}
Example of calling CoInitializeEx from Java code using JNA:
import com.sun.jna.platform.win32.Ole32;
public class Example {
public static void main(String[] args) {
Ole32.INSTANCE.CoInitializeEx(null,Ole32.COINIT_APARTMENTTHREADED);
}
}
Note that use of CoInitializeEx is recommended by both the JNA docs and the Windows SDK docs instead of CoInitialize. CoInitialize(null) is equivalent to CoInitializeEx(null,Ole32.COINIT_APARTMENTTHREADED), but the JNA docs recommend using COINIT_MULTITHREADED instead in Java apps (indeed, they call it "the only sane choice") – however, despite what they say, some COM interfaces only work correctly with COINIT_APARTMENTTHREADED, so it really depends on the COM objects you are using. Whichever you choose, CoInitializeEx is better because it makes it obvious (rather than implicit) which COM threading mode you are using.
Note the solution you mentioned in your comment, calling CoInitialize from within your DLL written in Delphi, is not a good practice. COM should be initialised in the application not in a DLL. If you ever attempt to reuse your DLL in some other application (which is already calling CoInitialize/CoInitializeEx), it is likely your call to it will fail with S_FALSE or RPC_E_CHANGED_MODE because the application will have already initialised it.

Call native JNI DLL from C#

I have a native DLL abc.dll (without source code) that was originally used in a JNI call in Java like this:
public class ABC_Proxy
{
private native void callABC(String parameter);
public ABC_Proxy()
{
System.loadLibrary("abc");
}
public void Start(String paramater)
{
callABC(paramater);
}
}
Now I am trying to execute the same function in C#. Using dumpbin I found the correct full entry point, and this is what I came up with so far:
class Abc
{
[DllImport("abc.dll", EntryPoint="_Java_my_namespace_abc_1Proxy_callABC#12")]
private static extern void CallAbc(string parameter);
public void Start(string parameter)
{
CallAbc("test");
}
}
I can see that CallAbc is executed and does something (it creates a file) but then it throws an AccessViolationException, presumably when it tries to access the parameter.
The PureDLLHelper suggests that the function has 3 parameters, and after reading this JNI tutorial I have the feeling that I also need to pass the parameters JNIEnv*, jobject to simulate a JNI call. But from here on I'm lost...
Any idea? Is it even possible what I'm trying to achieve?
Edit: I just want to mention this forum post that has a good explanation of the problems involved and how they could by solved. However, the solutions are based on Xamarin.Android to bridge the C#/Java gap and get hold of the JNIEnv, which is not really an option for me.
Its not going to work, simple as that. The JNI DLL is designed and built to be loaded by the JVM. You will not be able to provide the pointers to the env or jvm that are required to call any of the functions contained in that library. Your only option would be to create a second DLL that creates a new instance of the JVM that then calls the DLL you have, but if you are calling Java from .Net, you may as well keep it all in Java.

Categories