Collin Bell
Collin Bell

Reputation: 583

Why is clojure erroring with java.lang.IllegalAccessError when using proxy

I'm trying to use Twitter4j to access a user stream. The problem I am having is that I can not implement an interface and then use it as a listener.

Here is my code in full

(ns dameon.temporal-lobe.twitter
      (:import [twitter4j TwitterStreamFactory StatusListener StreamListener]
               [twitter4j.conf ConfigurationBuilder])
      (:require [clojure.edn :as edn :only [read-string]]))



;;The class that handles the stream data
(def status-listener
  (proxy [StatusListener] []
   (onStatus [status]
     (println status))
   (onDeletionNotice [status-deletion-notice])
   (onTrackLimitationNotice [number-of-limited-statuses])
   (onStallWarning [warning])
   (onException [ex]
     (.printStackTrace ex))
   (onScrubGeo [user-id up-to-status-id])))

(class status-listener)

;;Connect to the stream and add listener
(def creds (get (edn/read-string (slurp "creds.edn")) :twitter))

(-> (ConfigurationBuilder.)
    (.setDebugEnabled true)
    (.setOAuthConsumerKey (creds :consumer-key))
    (.setOAuthConsumerSecret (creds :consumer-secret))
    (.setOAuthAccessToken  (creds :access-token))
    (.setOAuthAccessTokenSecret (creds :access-secret))
    (.build)
    (TwitterStreamFactory.)
    (.getInstance)
    (.addListener status-listener)
    (.sample))

This is the error I get

 Unhandled java.lang.IllegalAccessError
   tried to access class twitter4j.StreamListener from class
   dameon.temporal_lobe.twitter$eval11235

Why is this? These interfaces are not private. They are just simple interfaces. What is going on?

Upvotes: 3

Views: 368

Answers (1)

Michał Marczyk
Michał Marczyk

Reputation: 84341

Assuming this is the implementation, twitter4j.StreamListener is declared with no explicit access modifier, and so it is visible only within its own package – see Gosling, Joy, Steele, Bracha, Buckley, The Java ® Language Specification. Java SE 8 Edition, §6.6.1 Determining Accessibility:

If a class or interface type is declared public , then it may be accessed by any code, provided that the compilation unit (§7.3) in which it is declared is observable.

If a class or interface type is declared with package access, then it may be accessed only from within the package in which it is declared.

A class or interface type declared without an access modifier implicitly has package access.

Upvotes: 3

Related Questions