javalib-team / sawja

Sawja provides a high level representation of Java bytecode programs and static analysis tools.
GNU General Public License v3.0
11 stars 4 forks source link

Support of default and static method in interfaces (Java 1.8) #6

Open Aaylor opened 2 years ago

Aaylor commented 2 years ago

Good evening,

We are using Sawja and Javalib in order to do some work with Java 1.8 bytecodes, and especially using the OpenJDK 1.8.0u292 Standard Library. We were first using the JCRA algorithm, without using method resolution yet, successfully [...]

Currently, we would like to try out the JRTA algorithm (or using method resolution), but we are facing issues with the Standard Library due to unsupported Java 1.8 features:

We took a look at the sources and saw that the different method resolution algorithm we found (e.g. in JControlFlow for example, or JRTA) that these specific features are not supported at all.

We tried to patch this on our side, but since we do not know enough the sources, we bet that this would not be enough. Is it planned to officially support these features from Java 1.8 ?


Here are two examples we failed to parse using JRTA, using the following program to parse them:

let ( // ) = Filename.concat
let openjdk_1_8_lib = "/usr/lib/jvm/java-8-openjdk-amd64"
let openjdk_1_8_classpath = openjdk_1_8_lib // "jre" // "lib"

let class_name = "Foo"
let class_name' = Javalib_pack.JBasics.make_cn class_name

let classpath = ".:" ^ openjdk_1_8_classpath

let entrypoint =
  Javalib_pack.JBasics.make_cms
    class_name'
    Sawja_pack.JProgram.main_signature

let _parse =
  Sawja_pack.JRTA.parse_program
    classpath
    entrypoint

The first example is about calling a static method declared in an interface (which is new in Java 1.8):

interface IFoo {
    public static int get() {
        return 42;
    }
}

public class Foo implements IFoo {
    static int X;
    public static void main(String[] args) {
        X = IFoo.get();
    }
}

But this example throws the following exception:

Fatal error: exception Failure("to_class_node applied on interface !")

The second example is about calling a default method declared in an interface (also new in Java 1.8):

interface IFoo {
    default int get() {
        return 42;
    }
}

public class Foo implements IFoo {
    static int X;
    public static void main(String[] args) {
        Foo foo = new Foo();
        X = foo.get();
    }
}

But this example throws the following exception:

Fatal error: exception Sawja_pack.JProgram.NoSuchMethodError

Thank you!

davidpichardie commented 2 years ago

Hi. This analysis has not been used for a while here. Did you even manage to make it work on a class without these features? I fear it will also break. I will have a look.

Aaylor commented 2 years ago

Hi,

On basic example, by setting both instantiated and other_entrypoints to empty lists (to avoid pulling out the a large part of the standard library), we managed to have working results. But since we would like to work on the standard library, it is not a viable solution. I admit we did not go further on our tries using JRTA.

Outside JRTA, the problem also exists because of JControlFlow that we need to use when working with JCRA: we need sometimes to resolve a method call, which fails when we encounter one of situation exposed in the first comment!

Thanks!