当类由 clojure 中的 gen-class 宏生成时出现 ClassNotFoundException

问题描述 投票:0回答:1

我有命名空间

myorg.helpers.fs-input-stream
-它的定义是

(ns myorg.helpers.fs-input-stream)
(gen-class
 :name "myorg.helpers.FsInputStream"
 :extends java.io.ByteArrayInputStream
 :implements [org.apache.hadoop.fs.Seekable org.apache.hadoop.fs.PositionedReadable]
 :main false
 :exposes {buf  {:get getBuf}
           pos  {:get getPos}
           mark {:get getMark}}
 :init-impl-ns false)

我有另一个命名空间

myorg.plugin.orc-output
,它使用上面命名空间生成的类。它的定义是-

(ns myorg.plugin.orc-output
  (:import
   [myorg.helpers.fs-input-stream FsInputStream]
   java.io.ByteArrayOutputStream
   java.lang.UnsupportedOperationException
   java.nio.ByteBuffer
   [java.net URL]
   [java.io File]
   [java.nio.file Path]
   org.apache.hadoop.conf.Configuration
   [org.apache.orc OrcFile]
   [org.apache.hadoop.fs FileSystem FileSystem$Statistics FSDataInputStream FSDataOutputStream]))

(set! *warn-on-reflection* true)

(defn to-path
  [x]
  {:post (instance? Path %)}
  (cond
    (instance? URL x) (Path. (.toURI ^URL x))
    (instance? File x) (Path. (.getPath ^File x))
    (string? x)                (Path. ^String x)
    (instance? Path x)         x))

(def dummy-path (to-path "dummy"))

(def orc-header-length (count OrcFile/MAGIC))

(defn input-stream-filesystem [buffered-bytes]
  (proxy [FileSystem] []
    (open [_]
      (FSDataInputStream. (FsInputStream. buffered-bytes)))))

(defn create-orc-reader [buffered-bytes]
  (OrcFile/createReader dummy-path (doto (OrcFile/readerOptions (Configuration.))
                                     (.maxLength (count buffered-bytes))
                                     (.filesystem (input-stream-filesystem buffered-bytes)))))

然后我测试了名为

myorg.plugin.orc-output
的命名空间
myorg.plugin.orc-output-test
。它有非常基本的测试

(ns myorg.plugin.orc-output-test
  (:require [clojure.test :refer :all])
  (:require [myorg.plugin.orc-output :refer :all]))

(deftest orc-create
  (is (= 1 1)))

当我在 Intellij Idea 中运行测试时,出现错误 -

在 (myorg/plugin/orc_output.clj:1:1) 处编译时出现语法错误 (ClassNotFoundException)。 myorg.helpers.fs-input-stream.FsInputStream

完整报告: /var/folders/b_/_t677thx43n6pd8l8x0c1qjr0000gp/T/clojure-13616919898936783952.edn

我该如何解决这个问题?

注意 - 该项目也在 github 中。

clojure clojure-java-interop clojure-testing
1个回答
0
投票

当使用

gen-class
作为宏时,而不是将其用作
ns
形式的一部分,您必须提供
:name
,它将生成的类的限定名称。到目前为止,一切都很好,除了您实际上不必在那里使用字符串 - 它也可以是一个符号:
:name myorg.helpers.FsInputStream

指定名称的类将在指定的包中生成,因此您必须这样导入它。这就是你犯错误的地方:

[myorg.helpers.fs-input-stream FsInputStream]
实际上应该是
[myorg.helpers FsInputStream]
(我会把它写成
(myorg.helpers FsInputStream)
)。

© www.soinside.com 2019 - 2024. All rights reserved.