最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How do I import a Java project from GitHub into a Clojure project? - Stack Overflow

programmeradmin5浏览0评论

I want my Clojure program to "look out at the world" through the camera. I found a Github project that does the work and is even written in Java. I got it to work using a 3-line piece of Java code. Then I thought, "I'll just convert it to Clojure using Java interop and go from there." But I don't know how.

Here's the Java code that read the camera, and wrote a one-frame JPG file to disk:

import com.github.sarxos.webcam.Webcam;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;

public class WebcamTutorial {

    public static void main (String[] args) {
        Webcam webcam = Webcam.getDefault();
        webcam.open();
        try {
            ImageIO.write(webcam.getImage(), "JPG", new File("C:\\Users\\Joe User\\Desktop\\firstCapture.JPG"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

Here's my Clojure attempt at doing the same thing:

(ns webcam2.core
  (:import java.io.File)
  (:import java.io.IOException)
  (:import javax.imageio.ImageIO)
  (:import com.github.sarxos.webcam.Webcam)

  (defn -main []
        ((let [webcam (Webcam. (getDefault.))]
           (webcam. open.)
           (ImageIO.write. webcam. getImage. "JPG", new .File ("C:\\Users\\Joe User\\Desktop\\firstClojureCapture.JPG"))
           )
         )
        )
  )

I'm getting "Unused Imports" errors on the 4 :import statements. And most vexing, I also get the error

com.github.sarxos.webcam.Webcam cannot be resolved

I do not know how to import a Github project into Clojure, or even if such a thing is possible.

I want my Clojure program to "look out at the world" through the camera. I found a Github project that does the work and is even written in Java. I got it to work using a 3-line piece of Java code. Then I thought, "I'll just convert it to Clojure using Java interop and go from there." But I don't know how.

Here's the Java code that read the camera, and wrote a one-frame JPG file to disk:

import com.github.sarxos.webcam.Webcam;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;

public class WebcamTutorial {

    public static void main (String[] args) {
        Webcam webcam = Webcam.getDefault();
        webcam.open();
        try {
            ImageIO.write(webcam.getImage(), "JPG", new File("C:\\Users\\Joe User\\Desktop\\firstCapture.JPG"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

Here's my Clojure attempt at doing the same thing:

(ns webcam2.core
  (:import java.io.File)
  (:import java.io.IOException)
  (:import javax.imageio.ImageIO)
  (:import com.github.sarxos.webcam.Webcam)

  (defn -main []
        ((let [webcam (Webcam. (getDefault.))]
           (webcam. open.)
           (ImageIO.write. webcam. getImage. "JPG", new .File ("C:\\Users\\Joe User\\Desktop\\firstClojureCapture.JPG"))
           )
         )
        )
  )

I'm getting "Unused Imports" errors on the 4 :import statements. And most vexing, I also get the error

com.github.sarxos.webcam.Webcam cannot be resolved

I do not know how to import a Github project into Clojure, or even if such a thing is possible.

Share Improve this question edited Mar 18 at 15:55 amalloy 92.3k8 gold badges148 silver badges213 bronze badges asked Mar 18 at 15:29 LionelGouletLionelGoulet 5792 silver badges13 bronze badges 7
  • 2 How do you make the webcam libs available to clojure? – Just another Java programmer Commented Mar 18 at 16:01
  • 3 What build tool are you using? Are the deps added there? The java there (roughly) translates to (let [webcam (doto (Webcam/getDefault) (.open))] (ImageIO/write (.getImage webcam) "JPG" (File. "/tmp/capture.jpg"))) -- but I highly recommend to familiarize yourself with how Java Interop works. – cfrick Commented Mar 18 at 16:07
  • The Webcam lib is on GitHub, here: github/sarxos/webcam-capture – LionelGoulet Commented Mar 19 at 14:13
  • I'm sorry I fot to mention I'm using the Clojure add-on to IntelliJ IDEA as a development environment. – LionelGoulet Commented Mar 19 at 14:16
  • I was trying on my macos - arm64 architecture - that became very complicated - because the package require x86_64 architecture ... – Gwang-Jin Kim Commented Mar 19 at 17:08
 |  Show 2 more comments

1 Answer 1

Reset to default 1

In Mac, I couldn't make it work because I have arm64 architecture (M3).

So I tried it in ubuntu and it worked.

Java

The detailed steps to make java run were:

# test that java is running
java -version

openjdk version "11.0.26" 2025-01-21
OpenJDK Runtime Environment (build 11.0.26+4-post-Ubuntu-1ubuntu122.04)
OpenJDK 64-Bit Server VM (build 11.0.26+4-post-Ubuntu-1ubuntu122.04, mixed mode, sharing)

which java # where is it running?

/usr/bin/java

# maven was not installed so installed it
sudo apt install maven

mvn -version

Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 11.0.26, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "6.8.0-52-generic", arch: "amd64", family: "unix"

# then I created a directory
mkdir -p ~/projects/java/
cd ~/projects/java

# and generated with maven a project called "webcam-test"

mvn archetype:generate -DgroupId=com.example -DartifactId=webcam-test -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

# which generated a folder with the structure

webcam-test
├── firstCapture.JPG
├── pom.xml
├── src/main/java/com/example/App.java

# nano pom.xml

# open pom.xml and add inside <dependencies></dependencies> this section:

<dependencies>



    <dependency>
        <groupId>com.github.sarxos</groupId>
        <artifactId>webcam-capture</artifactId>
        <version>0.3.12</version>
    </dependency>
    
    
    
</dependencies>

# and at the same level like <dependencies> add a section

<build>
    <plugins>
        <plugin>
            <groupId>.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>11</source>
                <target>11</target>
            </configuration>
        </plugin>
    </plugins>
</build>

# this avoids an error otherwise occurring - since java -version gave 11 as version
# it was important to ensure that 11 is used.

# so the full file content pom.xml:

<project xmlns="http://maven.apache./POM/4.0.0" xmlns:xsi="http://www.w3./2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache./POM/4.0.0 http://maven.apache./maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>webcam-test</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>webcam-test</name>
  <url>http://maven.apache.</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.github.sarxos</groupId>
        <artifactId>webcam-capture</artifactId>
        <version>0.3.12</version>
    </dependency>
  </dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>11</source>
                <target>11</target>
            </configuration>
        </plugin>
    </plugins>
</build>
</project>

# save and close it.

# then:
# nano src/main/java/com/example/App.java

# and enter the content:

package com.example;

import com.github.sarxos.webcam.Webcam;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;

public class App {
    public static void main(String[] args) {
        Webcam webcam = Webcam.getDefault();

        if (webcam == null) {
            System.out.println("No webcam detected!");
            return;
        }

        webcam.open();
        try {
            ImageIO.write(webcam.getImage(), "JPG", new File("firstCapture.JPG"));
            System.out.println("Image captured successfully!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            webcam.close();
        }
    }
}


# that is the script for ubuntu.

# save and close.

To build and run, from inside the webcam-test folder, run:

# build
mvn package

# run
mvn exec:java -Dexec.mainClass="com.example.App"

This should capture a picture and save as firstCapture.JPG.

Clojure

For Clojure, we want to ensure that Clojure uses the same Java. Therefore we define JAVA_HOME and add the binary folder into PATH:

export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
export PATH=$JAVA_HOME/bin:$PATH

To find out your exact path, do:

ls -l /usr/lib/jvm

and check the current running java version with

java -version

For me, this gave:

lrwxrwxrwx 1 root root   25 Mär 24  2022 default-java -> java-1.11.0-openjdk-amd64
lrwxrwxrwx 1 root root   21 Jul 21  2024 java-1.11.0-openjdk-amd64 -> java-11-openjdk-amd64
drwxr-xr-x 7 root root 4096 Mär 11 14:23 java-11-openjdk-amd64

# and:
openjdk version "11.0.26" 2025-01-21
OpenJDK Runtime Environment (build 11.0.26+4-post-Ubuntu-1ubuntu122.04)
OpenJDK 64-Bit Server VM (build 11.0.26+4-post-Ubuntu-1ubuntu122.04, mixed mode, sharing)

Don't do

export JAVA_HOME=$(which java)

I did it initially but that results in problems later. It should be a /usr/lib/jvm path.

Generate the folder and files:

mkdir -p ~/projects/clojure/clojure-webcam
cd ~/projects/clojure/clojure-webcam

Create deps.edn: nano deps.edn

{
  :paths ["src"]
  :deps {
    .clojure/clojure {:mvn/version "1.11.1"}
    com.github.sarxos/webcam-capture {:mvn/version "0.3.12"}
  }
}

You might need different version numbers in future. Today is March 20 2025

Create then the code folder and file:

mkdir -p src
nano src/webcam.clj

Enter the content:

(ns webcam
  (:import [com.github.sarxos.webcam Webcam]
           [javax.imageio ImageIO]
           [java.io File]))

(defn capture-image []
  (let [webcam (Webcam/getDefault)]
    (if (nil? webcam)
      (do
        (println "No webcam found!")
        (System/exit 1)) ;; Exit with error code
      (try
        (.open webcam)
        (ImageIO/write (.getImage webcam) "JPG" (File. "clojure-webcam.jpg"))
        (println "Image captured!")
        (catch Exception e
          (println "Error capturing image:" (.getMessage e)))
        (finally
          (when (.isOpen webcam)
            (.close webcam))))))) ;; Ensure webcam closes

(defn -main []
  (capture-image)
  (shutdown-agents) ;; Prevent lingering threads
  (System/exit 0))  ;; Exit gracefully

The try - catch - finally was necessary because some error occured while closing.

Alternatively use with-open

(ns webcam
  (:import [com.github.sarxos.webcam Webcam]
           [javax.imageio ImageIO]
           [java.io File Closeable]))

(defn capture-image []
  (let [webcam (Webcam/getDefault)]
    (if (nil? webcam)
      (do
        (println "No webcam found!")
        (System/exit 1))
      (with-open [w webcam]
        (.open w)
        (ImageIO/write (.getImage w) "JPG" (File. "clojure-webcam.jpg"))
        (println "Image captured!")))))

(defn -main []
  (capture-image)
  (shutdown-agents)
  (System/exit 0))

You can test first with

(let [webcam (Webcam/getDefault)]   
  (println "Implements Closeable? " (instance? java.io.Closeable webcam))      
  (println "Implements AutoCloseable? " (instance? java.lang.AutoCloseable webcam)))

Whether this would work. I didn't test the with-clojure expression.

Run the clojure program by:

clojure -M -m webcam

Error occurring without finally clause

Without the finally clause, I had this error occuring:

:~/projects/clj/clojure-webcam$ clojure -M -m webcam
SLF4J: Failed to load class ".slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j./codes.html#StaticLoggerBinder for further details.
Image captured!
Execution error (NullPointerException) at clojure.main/main (main.java:40).
null

Full report at:
/tmp/clojure-18393721443446853860.edn

And the report's content was:

  GNU nano 6.2                                      /tmp/clojure-18393721443446853860.edn                                                
{:clojure.main/message
 "Execution error (NullPointerException) at clojure.main/main (main.java:40).\nnull\n",
 :clojure.main/triage
 {:clojure.error/class java.lang.NullPointerException,
  :clojure.error/line 40,
  :clojure.error/symbol clojure.main/main,
  :clojure.error/source "main.java",
  :clojure.error/phase :execution},
 :clojure.main/trace
 {:via
  [{:type java.lang.NullPointerException,
    :at [clojure.core$apply invokeStatic "core.clj" 667]}],
  :trace
  [[clojure.core$apply invokeStatic "core.clj" 667]
   [clojure.main$main_opt invokeStatic "main.clj" 514]
   [clojure.main$main_opt invoke "main.clj" 510]
   [clojure.main$main invokeStatic "main.clj" 664]
   [clojure.main$main doInvoke "main.clj" 616]
   [clojure.lang.RestFn applyTo "RestFn.java" 137]
   [clojure.lang.Var applyTo "Var.java" 705]
   [clojure.main main "main.java" 40]]}}

And the original code with this error was:

(ns webcam
  (:import [com.github.sarxos.webcam Webcam]
           [javax.imageio ImageIO]
           [java.io File]))

(defn capture-image []
  (let [webcam (Webcam/getDefault)]
    (if (nil? webcam)
      (println "No webcam found!")
      (do
        (.open webcam)
        (ImageIO/write (.getImage webcam) "JPG" (File. "clojure-webcam.jpg"))
        (println "Image captured!")
        (.close webcam)))))

(capture-image)

I didn't figured out what the error was exactly - maybe someone has an idea?

Anyhow that's it - this works in ubuntu.

发布评论

评论列表(0)

  1. 暂无评论