46

I am getting a strange runtime error from my code:

"Found interface [SomeInterface] but class was expected"

How can this happen? How can an interface get instantiated?

Update: (In response to some answers) I am compiling and running against the same set of libraries, but I am using Guice to inject a Provider for this particular Interface.

The problem went away when I bound an implementation to the interface (seems like the @ImplementedBy annotation was not enough).

I was more interested in the mechanics through which Guice managed to actually instantiate an interface.

levik
  • 114,835
  • 27
  • 73
  • 90

5 Answers5

80

This happens when your runtime classpath is different than your compile time classpath.

When your application was compiled, a class (named SomeInterface in your question) existed as a class.

When your application is running at compile time, SomeInterface exists as an interface (instead of a class.)

This causes an IncompatibleClassChangeError to be thrown at runtime.

This is a common occurence if you had a different version of a jar file on the compile time classpath than on the runtime classpath.

Jared
  • 25,520
  • 24
  • 79
  • 114
  • The stack trace was purely in my own code (and would therefore be useless to anyone else). This is what I found weird. It almost looked like Guice was succeeding in creating an instance of an Interface. – levik Feb 26 '09 at 17:11
  • I have the same issue. It happened when I tried to install joodo (a Clojure framework) and now `lein` commands won't work. How do I resolve this? – rzv Nov 30 '12 at 22:38
  • Same weirdness can occur with Mockito when mocking the interface. I discovered today... – Dave May 26 '14 at 07:08
  • Nice. I encountered this in a Maven project when I changed an interface to an abstract class. So just do `mvn clean` first. – skytreader Nov 06 '14 at 02:49
  • 1
    It can happen in multi module projects as well. Doing a full rebuild of the project can help to solve it. – Sunil Kumar Jul 25 '19 at 09:57
  • A plausible situation is when you update one jar from your dependency list, but you do not update its dependencies. Therefore, if the main new jar was compiled with a newer version of its dependency jars, then this error may occur. – Victor May 20 '20 at 15:40
8

Most likely the code was compiled against a class in a library, which was then changed to an interface in the version you run against.

starblue
  • 55,348
  • 14
  • 97
  • 151
2

I had the same problem. I use two jar libraries in my application. One library is built upon the other.

The library A defines top classes and interfaces. Library B requires library A.

This is pseudocode of some code used in library B:

TheInterface instance = new TheClass();
instance.someMethod();

Apparently library A is newer than library B and TheInterface doesn't contain someMethod anymore, but TheClass still does. The only way to fix this is to get the source for either jar and change these things by hand (if at all possible).

Mark Jeronimus
  • 9,278
  • 3
  • 37
  • 50
2

This happened to me when i was running a maven build.

From what i could gather (as well as from Jared's answer) as the reason was that - there were two versions of the same 3rd party jar specified in my effective pom.xml. One version was coming in as a transitive dependency and the other was specified by me in my local pom.xml.

So at compile time, it was referring to the old version and at runtime it was referring to the new version.

I removed the version specified in my local pom.xml and it worked.

Of course, the 3rd party had broken backward-compatibility between their versions and changed a class to an interface or vice-versa. But they are free to do so.

Yuriy Tsarkov
  • 2,461
  • 2
  • 14
  • 28
Pradeep Anchan
  • 1,469
  • 1
  • 11
  • 11
1

It sounds like you did

class MyClass extends SomeInterface

when it should actually be

class MyClass implements SomeInterface

Am I right?

EDIT: Oh, you say it's a runtime error and not a compile-time error? Let me look around a bit...

EDIT 2: It looks like Jared has the correct answer. Anyway, trying to extend an interface would actually give a "no interface expected here" message at compile time, not a "found interface but class was expected" error.

Michael Myers
  • 188,989
  • 46
  • 291
  • 292