This is quite detailed so please bear with me.
I am connecting a hardware device to my Swing application (Yes, Swing). This device is a camera for iris biometric data capture.
In my project, I have a device monitor class that listens for connections or disconnections from this device. This is implemented like this in the class DeviceMonitorThread
which extends Thread
private static boolean monitorDevices = true;
private boolean irisScannerConnectionStatus = false;
...
private synchronized boolean checkIrisScannerConnectivity() {
logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>>Checking iris scanner connectivity...");
Controller.deviceMonitorIrisScannerOn = true;
if (Controller.irisScannerOn) {
logger.debug(">>>>>>>>>>>>> Iris camera is connected so device monitor thread was skipped...");
Controller.deviceMonitorIrisScannerOn = false;
return true;
}
try {
if (Controller.iIrisCam == null) {
Controller.iIrisCam = new IrisCamJNI();
}
Controller.iIrisCam.connectToCameraIndex(0);
irisScannerConnectionStatus = Controller.iIrisCam.isCameraConnected();
logger.debug(irisScannerConnectionStatus ? ">>>>>>>>>>>>>>>>>Iris Scanner is connected" : "Iris scanner is not connected");
if (irisScannerConnectionStatus) {
try {
logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>.Disconnecting iriscam");
Controller.iIrisCam.disconnect();
} catch (IrisCamException irisCamException) {
logger.error("[Error]", irisCamException);
} catch (Exception exception) {
logger.error("ERROR ", exception);
} catch (Error error) {
logger.error("Error", error);
throw new Error(error);
}
return true;
}
} catch (IrisCamException exception) {
logger.error(">>>>>>>>>> Error initializing IrisCam object...........", exception);
}
return false;
}
This is the run()
method:
@SuppressWarnings("SleepWhileInLoop")
@Override
public void run() {
while (monitorDevices) {
if (!monitorDevices) {
break;
}
try {
logger.debug(">>>>>>>>>>>>>About to check irisScannerConnectivity()...");
boolean newIrisScannerConnectionStatus = checkIrisScannerConnectivity();
logger.debug(">>>>>>>>newIrisScannerConnectionStatus = " + newIrisScannerConnectionStatus);
if (newIrisScannerConnectionStatus != irisScannerConnectionStatus) {
irisScannerConnectionStatus = newIrisScannerConnectionStatus;
}
} catch (Exception e) {
logger.error(e.getMessage());
}
notifyListeners();
try {
if (!monitorDevices) {
break;
}
Thread.sleep(THREAD_SLEEP_INTERVAL);
if (systemExited) {
monitorDevices = false;
}
} catch (InterruptedException e) {
logger.error("Thread Interrutped: ", e);
} catch (Exception e) {
logger.error("Exception in device monitor thread");
}
}
}
iIrisCam
and the other booleans are declared in the Controller class as thus:
public static IIrisCam iIrisCam;
public static boolean irisScannerOn, deviceMonitorIrisScannerOn = false;
Now, when I run this app. I have to keep my fingers crossed because this crash DOESN'T ALWAYS happen. It crashes now, and the next time I am able to capture the images or it crashes a couple of times in a row and so on.
When It does crash, this is the error message I get:
With the all mighty
This project uses a lot of .dll
files (placed in the System32
and sysWOW64
folders) from the IIrisCam SDK.
I have done lots of logging but the cause of this error never seems to be caught. My guess is this has to do with memory being used and not released. I'll provide more information for anyone willing to help.
if it's of any relevance, I am using a 64bits windows 10 computer, while the IIrisCam sdk uses a lot of 32bit stuff.
Edit
This is what the run.xml
file referenced in the error message looks like:
<project name="{0} (run)" default="run" basedir=".">
<target name="run">
<translate-classpath classpath="${classpath}" targetProperty="classpath-translated" />
<property name="run.jvmargs" value="" />
<property name="work.dir" value="${basedir}"/>
<property name="application.args" value="" />
<property name="java.failonerror" value="true"/>
<java classpath="${classpath-translated}" classname="${classname}" dir="${work.dir}" jvm="${platform.java}" fork="true" failonerror="${java.failonerror}">
<jvmarg value="-Dfile.encoding=${encoding}"/>
<redirector inputencoding="${encoding}" outputencoding="${encoding}" errorencoding="${encoding}"/>
<jvmarg line="${run.jvmargs}" />
<arg line="${application.args}" />
<syspropertyset>
<propertyref prefix="run-sys-prop."/>
<mapper from="run-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
</java>
</target>