Skip to content

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

@mxprshn

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

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