siom79 / japicmp

Comparison of two versions of a jar archive
https://siom79.github.io/japicmp
Apache License 2.0
712 stars 107 forks source link

Moving an interface up to a superclass is flagged as breaking change #271

Closed yschimke closed 3 years ago

yschimke commented 4 years ago

Was

okhttp3.mockwebserver.MockWebServer <- Closeable

After

mockwebserver.MockWebServer <- Closeable okhttp3.mockwebserver.MockWebServer <- MockWebServer()

https://github.com/square/okhttp/pull/6317/files

Comparing binary compatibility of  against 
***! MODIFIED CLASS: PUBLIC FINAL okhttp3.mockwebserver.MockWebServer  (not serializable)
    ===  CLASS FILE FORMAT VERSION: 52.0 <- 52.0
    ---! REMOVED INTERFACE: java.io.Closeable
    ---! REMOVED INTERFACE: java.lang.AutoCloseable
siom79 commented 4 years ago

Which version are you using? This should be working since version 0.7.2 (see #123).

yschimke commented 4 years ago

I think it's well ahead of that version.

https://github.com/square/okhttp/blob/master/build.gradle#L70

id "me.champeau.gradle.japicmp" version "0.2.9"

https://github.com/melix/japicmp-gradle-plugin/blob/master/gradle/compile.gradle#L25

com.github.siom79.japicmp:japicmp:0.14.0

yschimke commented 4 years ago

The superclass is a new class if that helps.

siom79 commented 4 years ago

I have created a test case similiar to yours and get the following output:

===  UNCHANGED INTERFACE: PUBLIC ABSTRACT org.example.Closable  (not serializable)
    ===  CLASS FILE FORMAT VERSION: 51.0 <- 51.0
    ===  UNCHANGED SUPERCLASS: java.lang.Object (<- java.lang.Object)
    ===  UNCHANGED METHOD: PUBLIC ABSTRACT void close()
***  MODIFIED CLASS: PUBLIC org.example.MockWebServer  (not serializable)
    ===  CLASS FILE FORMAT VERSION: 51.0 <- 51.0
    ===  UNCHANGED INTERFACE: org.example.Closable
    ***  MODIFIED SUPERCLASS: org.example.MockWebServerNewSuperClass (<- java.lang.Object)
    ===  UNCHANGED CONSTRUCTOR: PUBLIC MockWebServer()
    ===  UNCHANGED METHOD: PUBLIC void close()
    ===  UNCHANGED METHOD: PUBLIC STATIC void main(java.lang.String[])
+++  NEW CLASS: PUBLIC(+) org.example.MockWebServerNewSuperClass  (not serializable)
    +++  CLASS FILE FORMAT VERSION: 51.0 <- n.a.
    +++  NEW INTERFACE: org.example.Closable
    +++  NEW SUPERCLASS: java.lang.Object
    +++  NEW CONSTRUCTOR: PUBLIC(+) MockWebServerNewSuperClass()
    +++  NEW METHOD: PUBLIC(+) void close()

You see that in the new version MockWebServer extends MockWebServerNewSuperClass:

public class MockWebServer extends MockWebServerNewSuperClass

And MockWebServerNewSuperClass implements the interface:

public class MockWebServerNewSuperClass implements Closable {

Can you post the complete output of your class structure?

yschimke commented 4 years ago

I wonder if it is the behaviour of the kotlin compiler.

I'm not actually sure how to get the output before the diff. I'm looking at https://github.com/melix/japicmp-gradle-plugin