ClassNotFoundException when the class is generated by gen-class macro in clojure

68 Views Asked by At

I've namespace myorg.helpers.fs-input-stream -Its definition is

(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)

I've another namespace myorg.plugin.orc-output which uses the class generated by above namespace. Its definition is -

(ns myorg.plugin.orc-output
  (:import
   (myorg.helpers FsInputStream)
   (org.apache.hadoop.fs FileSystem FSDataInputStream)))

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


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

Then I've test for namespace myorg.plugin.orc-output called myorg.plugin.orc-output-test. It has very basic 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)))

When I run the test in Intellij Idea I get error-

Syntax error (ClassNotFoundException) compiling at (myorg/plugin/orc_output.clj:1:1). myorg.helpers.fs-input-stream.FsInputStream

Full report at: /var/folders/b_/_t677thx43n6pd8l8x0c1qjr0000gp/T/clojure-13616919898936783952.edn

How can I fix this?

Note - The project is in github as well.

1

There are 1 best solutions below

2
On

When using gen-class as a macro, as opposed to using it as a part of the ns form, you have to provide a :name that's a qualified name of the class that will be generated. So far, all good, except that you don't really have to use a string there - it can be a symbol as well: :name myorg.helpers.FsInputStream.

The class with the specified name will be generated in the specified package, so you have to import it as such. And that's where you've made a mistake: [myorg.helpers.fs-input-stream FsInputStream] should actually be [myorg.helpers FsInputStream] (I'd write it as (myorg.helpers FsInputStream)).