-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
java.util.concurrent.RejectedExecutionException and JVM crashes sometimes #228
Comments
Hi @kaustubhasgudi, Do not modify the lock state unless you are completely aware of what you are doing. Especially on Windows. Locking has been designed to get rid of weird Microsoft issues with accessing DirectShow from two parallel contexts, which in some cases causes JVM to crash. You do not also need to use webcam device because all the information you are getting from it are already available from webcam object. Modified source code: import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamException;
import com.github.sarxos.webcam.WebcamResolution;
public class X {
private static final Logger LOGGER = LoggerFactory.getLogger(X.class);
private static final String WEBCAMSHOTS_DIR = "./dir";
private static final String WEBCAMSHOT_FILE_NAME = "test.jpg";
public static void main(String[] args) {
new X().capture();
}
private void capture() {
int delay = 3; // 3 seconds, but you can set it to whatever you want
Dimension size = WebcamResolution.VGA.getSize();
Webcam defaultWebcam = Webcam.getDefault();
if (defaultWebcam == null) {
LOGGER.error("There is no webcam detected in the system");
return;
}
try {
defaultWebcam.setViewSize(size);
defaultWebcam.open();
captureWebcamImage(defaultWebcam, delay);
} catch (Exception e) {
e.printStackTrace();
} finally {
defaultWebcam.close();
}
}
private void captureWebcamImage(Webcam defaultWebcam, int delay) throws InterruptedException, WebcamException, IOException {
Dimension resolution = defaultWebcam.getViewSize();
Dimension[] resolutions = defaultWebcam.getViewSizes();
LOGGER.info(String.format("Webcam device: %s", defaultWebcam.getName()));
LOGGER.info(String.format("Webcam current resolution: %dx%d", resolution.width, resolution.height));
StringBuilder sb = new StringBuilder();
String delimiter = "";
for (Dimension r : resolutions) {
sb.append(delimiter).append(String.format("%dx%d", r.width, r.height));
delimiter = ", ";
}
LOGGER.info(String.format("Webcam supported resolutions: %s", sb.toString()));
if (delay > 0) {
LOGGER.info(String.format("Waiting %d seconds...", delay));
Thread.sleep(TimeUnit.MILLISECONDS.convert(delay, TimeUnit.SECONDS));
}
final BufferedImage img = defaultWebcam.getImage();
if (img == null) {
throw new WebcamException("The webcam is not available.");
}
LOGGER.info(String.format("Taking a %dx%d image...", img.getWidth(), img.getHeight()));
new File(WEBCAMSHOTS_DIR).mkdir();
final String imageName = WEBCAMSHOTS_DIR + File.separator + WEBCAMSHOT_FILE_NAME;
final File imageFile = new File(imageName);
if (!imageFile.exists()) {
LOGGER.debug(String.format("The image file does not exist, creating: %s", imageFile));
if (!imageFile.createNewFile()) {
throw new WebcamException("The image file cannot be created.");
}
}
ImageIO.write(img, "JPG", imageFile);
ClientState.getInstance().setWebcamImage(img);
}
public File getWebcamImageFile() {
return new File(WEBCAMSHOTS_DIR, WEBCAMSHOT_FILE_NAME);
}
} The exception you've observed is harmless and you can simply ignore it, but still I did small change in the source code which should get rid of it in the future. Please donate to the project if you consider this information as useful. |
The JAR with this fix is available here: |
Hi @sarxos Thanks for your quick reply. But removing lock/unlock didn't help. The tool still crashes and I am able to reproduce the crash myself. I have even tried to open the webcam in both synchronous and asynchronous modes using : defaultWebcam.open(); and defaultWebcam.open(true); I even observed that once I try to test the webcam using a single call to webcam.getImage(), CPU raises to 25% and doesn't come down at all despite closing the webcam and releasing all resources. I'm not sure the CPU consumption is attributed to the above error but the JVM crash and CPU consumption are closely associated as it seems. Can you suggest any workaround/solution for this ? |
Oh. sorry. I missed the jar file update. I'll try it and get back . |
This is strange. Is it reproducible on other computers? I had pretty similar situation in the past but it was caused by the fact that I was killing application simultaneously, without releasing resources. In such case, when I ran it again, I observed JVM crash and I had to restart Windows to get rid of this problem. However, if the problem you are reporting is not directly caused by such application killing, I'm not sure of how to resolve it. I would suggest to test if this problem can be observed on other computers. It may be that some application/driver in the middle is causing this (e.g. some buggy DirectShow filter) and not the library itself. When Java HotSpot crashes it drops |
The JAR I uploaded is to fix this |
Hi @sarxos Here is one such HotSpot Error Log file :
|
Issue is reproducible in at least 4 machines. I think looking at the problem frame it's related to bridj.jar but may be I am missing something. |
We can see that the crash is caused by the illegal access exception on BridJ
Before we move with this issue, I would like you to check if this specific issue is reproducible with newest and older BridJ versions. Can you please try again with the following JARs?
There is another thing which bothers me, but it's probably not connected with the crash. I see there are several webcam updaters alive on the threads list:
This must be some bug because it should be only one per webcam instance. From the log I see you are using only one webcam (ThinkVantage Virtual Camera 0) and you have 6 updaters. I will need to investigate this. Will keep you informed. Please let me know if the problem exists with other BridJ versions. |
Hi @sarxos I'll check the jars as you mentioned. And for the multiple webcam-updater threads I have a doubt as to whether they are due to the design of the application I am working upon. The application I am working upon schedules a webcam capture to be taken every 10 minutes using cron scheduler. So could be possible that all other threads didn't finalise due to an exception which ultimately caused the application to crash. May be I am missing something but I will investigate that . |
There was a bug in the code. There was two distinct mechanisms in one class - one designed to update image reference working only when webcam is in async mode, and second one to perform listeners notifications whenever new image is available. Both used same thread factory and so notificators were visible ad updater threads, which was wrong. The other issue is the fact that the executor controlling notificators was never shutdown, so in some situations these threads could possibly spawn again and again... This is now fixed. Ah, and it was not connected with the JVM crash. |
HotSpot Error obtained on using the new jar
|
The last fix wasn't to address JVM crash issue. Have you verified it with |
Yes. Just finished testing with other BridJ versions and tested in all 4 systems. None of them seem to keep the app stable. With newer version of BridJ the crash is definite after starting the app and continuing with it for 3 hrs. . With the official jars the crash is not frequent and needs some unpleasant activity in the system relevant to the crash. I'm working on to fix some stability issues with my app threads as some of them are spawned unnecessarily but I probably would say they didn't cause the crash as such. Still not sure what caused the crash. Just investigating :) |
Can you please prepare the log with DEBUG prints from the app? Here is the instruction of how to enable full debug for Webcam Capture, OpenIMAJ and BridJ: https://github.com/sarxos/webcam-capture/wiki/How-To-Enable-Dubug-Logs This is important to understand what is happening under the hood. I think that some references are being deleted before finalizer process them, which later causes JVM to crash because the memory reserved by instance to be released is already deallocated. The BridJ seems to work as expected. The void JNICALL Java_org_bridj_JNI_free(JNIEnv *env, jclass clazz, jlong ptr) {
BEGIN_TRY_CALL(env);
free(JLONG_TO_PTR(ptr));
END_TRY_CALL(env);
} And OpenIMAJGrabber::~OpenIMAJGrabber(){
if(((videoData*)this->data)->buffer!=NULL)
delete[] ((videoData*)this->data)->buffer;
delete ((videoData*)this->data)->VI;
delete ((videoData*)this->data);
} Which IMHO causes JVM crash, but we need strong prove for this. I understand that your application is active for many hours, when it open the webcam once per 10 minutes, take the picture and then close? Is this the case? Does it crash while running or when you close it? |
Yes. It's a multithreaded application (11 threads for different purposes) using cron scheduler and webcam takes pictures randomly once every 10 mins. And yes it crashes while running all of a sudden right after webcam.close() is called , although when I investigated more thoroughly I saw webcam did capture the image , image was saved and webcam thread (SwingWorker) as it needs to become free it crashes with the above error. I'll start the app with debug logs enabled and get back. |
Ok, and is the webcam invoked from all the threads, or only from one? |
@kaustubhasgudi, is the issue reproducible when you create very basic example doing nothing but opening the webcam once per 10 minutes, taking the image and then closing it? Here is the code. Can you please run it for several hours to verify if it creates the problem? import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.github.sarxos.webcam.Webcam;
public class NeverEndingLoopExample {
public static void main(String[] args) throws IOException, InterruptedException {
Webcam.getDiscoveryService().setEnabled(false);
Webcam webcam = Webcam.getDefault();
File file = new File("test.jpg");
do {
webcam.open();
ImageIO.write(webcam.getImage(), "JPG", file);
webcam.close();
Thread.sleep(1000 * 60 * 10); // sleep 10 minutes
} while (true);
}
} Also, can you try adding this line in your code, just before you start using Webcam.getDiscoveryService().setEnabled(false); |
Hi @sarxos I noticed one strange thing in one of the machines here. After installing gStreamer WinLibs + updating the webcam driver there isn't any crash anymore. In another machine where I work most of the times, there seems to be a jre issue. It was using jre 1.6 x32 and I had to install x64 as the operating system was x64 bit. I'll try with the sample you just posted above. I just don't want to deal with multiple issues here arising due to multiple environments and want to focus on just the crash so that I can delineate between compatibility issues and fixes required for webcam-capture jar. The webcam is invoked only once and it's a singleton called using a SwingWorker. But in another machine if I run using jre 1.7 through command prompt there is a JVM crash but if I run using jre 1.6 no crash. I am not sure if higher version is not supported in this case. Just investigating. Sorry for the late reply. I've been very sick since few days and unable to give time to work. |
Hi @kaustubhasgudi, I hope you are feeling much better now :) The native drivers causes problems very often. Some of them are not very good quality, may not support the standards, and thus, some hax in the code may be required be added, but unfortunately there is no room for such thing in Java since the API exposed from natives is very thin :( I never tried using 32-bit Java on 64-bit system, but this may, in theory, cause problem as well, since, depending on what arch is detected, different DLL is loaded in runtime (different for win 32- and 64-bit). The higher version of JRE should not make any problems. I was testing on 6, 7 and 8 with every of these releases working just fine. |
@kaustubhasgudi, I just verified that there is no issue when using newest Webcam Capture API + gstremaer-driver on 64-bit Windows 7 and 32-bit Java 8. |
Hello
I receive this exception from webcam-capture library :
Environment Details :
Windows 7 Professional SP1 x64
JDK 1.7.0_45 x64
WebCam : Lenovo Think Advantage webcam for Lenovo Thinkpad T430
Libraries :
bridj-0.7-20131007.003529-54.jar
webcam-capture-0.3.10-RC6
Given below is the code for webcam capture :
Most of the time the webcam capture process works fine but less often it show the above exception and sometimes the application silently exits (JVM crash). Please assist.
The text was updated successfully, but these errors were encountered: