Skip to content

Invalid jcdbName for classes which name starts with "L" without packages  #229

Description

@mxprshn

If there is a Java class where no package is specified, and its name starts with "L", the following method makes its name invalid:

fun String.jcdbName(): String {
return when {
this == "Z" -> PredefinedPrimitives.Boolean
this == "B" -> PredefinedPrimitives.Byte
this == "C" -> PredefinedPrimitives.Char
this == "S" -> PredefinedPrimitives.Short
this == "I" -> PredefinedPrimitives.Int
this == "F" -> PredefinedPrimitives.Float
this == "J" -> PredefinedPrimitives.Long
this == "D" -> PredefinedPrimitives.Double
this == "V" -> PredefinedPrimitives.Void
startsWith("[") -> {
val elementName = substring(1, length)
elementName.jcdbName() + "[]"
}
startsWith("L") -> {
substring(1, length - 1).replace('/', '.')
}
else -> this.replace('/', '.')
}
}

Example

For example, if there is a project with following classes:

// No package specified
public class LClass {
    public int f = 10;
}
// No package specified
public class MainClass {
    public LClass doStuffWithLClass() {
        LClass lClass = new LClass();
        lClass.f = 42;
        return lClass;
    }
}

then the following main fails with java.lang.IllegalStateException: Could not find type Clas at org.jacodb.impl.cfg.JcInstListBuilder.asType(JcInstListBuilder.kt:66) when getInstList() is called. As we can see, meaning letters from the "LClass" are removed by jcdbName(), and it turns just into "Clas"

import org.jacodb.api.JcClassOrInterface;
import org.jacodb.api.JcClasspath;
import org.jacodb.api.JcDatabase;
import org.jacodb.api.JcMethod;
import org.jacodb.api.cfg.JcInstList;
import org.jacodb.impl.JacoDB;
import org.jacodb.impl.JcSettings;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;

public class Main {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        String classpath = MainClass.class.getProtectionDomain().getCodeSource().getLocation().getPath();
        List<File> classpaths = Arrays.asList(new File(classpath));
        JcDatabase database = JacoDB.async(
                new JcSettings()
                        .useProcessJavaRuntime()
                        .loadByteCode(classpaths)
        ).get();

        JcClasspath jcClasspath = database.asyncClasspath(classpaths).get();
        JcClassOrInterface mainClass = jcClasspath.findClassOrNull("MainClass");
        JcMethod doStuffWithLClassMethod =
                mainClass.getDeclaredMethods().stream().filter((m) -> m.getName().contains("doStuffWithLClass")).toList().get(0);
        JcInstList instList = doStuffWithLClassMethod.getInstList(); // Fails with exception
    }
}

Environment

JacoDB version: 1.4.5

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions