Skip to content

Instantly share code, notes, and snippets.

@michael-simons
Last active October 11, 2024 19:02
Show Gist options
  • Select an option

  • Save michael-simons/6c472f50dcc9805dc7ee397adc097ea5 to your computer and use it in GitHub Desktop.

Select an option

Save michael-simons/6c472f50dcc9805dc7ee397adc097ea5 to your computer and use it in GitHub Desktop.

Revisions

  1. michael-simons revised this gist Oct 11, 2024. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion GoCyclingWithNeo4j.java
    Original file line number Diff line number Diff line change
    @@ -20,7 +20,7 @@ static class A {
    }

    static class B {
    static int lb = A.s.length();
    static int la = A.s.length();
    static String s = "Salat";
    }

  2. michael-simons revised this gist Oct 11, 2024. 1 changed file with 27 additions and 2 deletions.
    29 changes: 27 additions & 2 deletions GoCyclingWithNeo4j.java
    Original file line number Diff line number Diff line change
    @@ -14,11 +14,36 @@

    class GoCyclingWithNeo4j {

    static class A {
    static String s = "Wurst";
    static int lb = B.s.length();
    }

    static class B {
    static int lb = A.s.length();
    static String s = "Salat";
    }

    public static void main(String... a) throws IOException {

    if (a.length != 1) {
    System.err.println("Usage: GoCyclingWithNeo4j.java <jvm.log>");
    System.exit(0);
    System.err.println("""
    This program will crash, run with
    ```
    jbang -R-Xlog:class+resolve=trace:file=jvm.log
    ```
    to log the resolving of classes.
    After that, run
    ```
    jbang GoCyclingWithNeo4j.java jvm.log
    ```
    and see the circle between static inner classes A and B.
    """);
    new B();
    }

    var parameters = new ArrayList<Map<String, Object>>();
  3. michael-simons created this gist Oct 11, 2024.
    59 changes: 59 additions & 0 deletions GoCyclingWithNeo4j.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,59 @@
    ///usr/bin/env jbang "$0" "$@" ; exit $?
    //JAVA 17
    //DEPS org.neo4j:neo4j:5.24.1

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.util.ArrayList;
    import java.util.Map;
    import java.util.concurrent.atomic.AtomicLong;

    import org.neo4j.dbms.api.DatabaseManagementServiceBuilder;

    class GoCyclingWithNeo4j {

    public static void main(String... a) throws IOException {

    if (a.length != 1) {
    System.err.println("Usage: GoCyclingWithNeo4j.java <jvm.log>");
    System.exit(0);
    }

    var parameters = new ArrayList<Map<String, Object>>();
    try (var reader = new BufferedReader(Files.newBufferedReader(Path.of(a[0])));
    var lines = reader.lines()
    ) {
    var cnt = new AtomicLong(0);
    lines.forEach(l -> {
    var columns = l.split(" ");
    parameters.add(Map.of("source", columns[1], "target", columns[2], "at", columns.length >= 4 ? columns[3] : "n/a", "idx", cnt.incrementAndGet()));
    });
    }

    var dbms = new DatabaseManagementServiceBuilder(Files.createTempDirectory("neo4j"))
    .build();

    var db = dbms.database("neo4j");
    // Create graph
    db.executeTransactionally("""
    UNWIND $parameters AS r
    MERGE (f:Class {name: r.source})
    MERGE (t:Class {name: r.target})
    CREATE (f)-[:RESOLVED {at: r.at, idx: r.idx}]->(t)
    """, Map.of("parameters", parameters));

    // Query graph
    var candidates = db.executeTransactionally("""
    MATCH (start:Class WHERE start.name <> 'resolve')-[r:RESOLVED]->(end:Class)
    WHERE EXISTS { (start)((a)-[:RESOLVED]-(b) WHERE (a = start AND b = end) OR (a = end AND b = start) ){3,}(end) }
    AND start <> end
    RETURN start.name AS source, end.name AS target, r.at AS at
    ORDER BY r.idx
    """, Map.of(), rows -> rows.stream().toList());

    candidates.forEach(System.out::println);
    dbms.shutdown();
    }
    }