javamacosopencvkotlinjavacv

OpenCV Frame Grabber not work on MacOS Catalina


Short version:

when I'm type this command in macOS Catalina terminal:

java -jar test-1.0-SNAPSHOT.jar

gets the result:

Start App
zsh: abort         java -jar test-1.0-SNAPSHOT.jar

More details:

My main feature in app is based on webcam capture and I have a requirement for the application to work on Windows 10, Linux and MacOS. That's why I decided to choose JavaCV to handle webcam capturning. Everything works fine on windows and linux. However, it doesn't work properly on MacOS. For testing the application on a Mac, I'm using virtual box 6.1 and macOS Catalina 10.15.5. In project I'm also using gradle and kotlin.

I also checked if I have access to the camera from virtual machine and the camera works correctly in system applications. I suspect that the application is not working due to camera permissions.

I will also add that the macOS Catalina is up to date

Basic code

build.gradle:

plugins {
    id 'java'
    id 'org.jetbrains.kotlin.jvm' version '1.3.72'
    id 'application'
}

group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    testCompile group: 'junit', name: 'junit', version: '4.12'

    compile group: 'org.bytedeco', name: 'javacv-platform', version: '1.5.3'
}

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

jar {
    manifest {
        attributes "Main-Class": "App"
    }
    from {
        configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
    }

    exclude('META-INF/*.SF')
    exclude('META-INF/*.DSA')
    exclude('META-INF/*.RSA')
    exclude('module-info.class')
}
mainClassName = 'App'

App.kt

import org.bytedeco.javacv.OpenCVFrameGrabber

class App {
    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
            println("Start App")
            val grabber: OpenCVFrameGrabber = OpenCVFrameGrabber(0);
            grabber.start()
        }
    }
}

In order to create executable jar file, I'm type this in mac terminal:

sudo 
./gradlew clean build

Solution

  • I solved my problem. The problem with macOS was that the app should ask for camera access before launching it. Jar files are not treated as applications by macOS. More info here. For example, when you running the application by IDE, system will ask you for access to the camera.