codespecs / daikon

Dynamic detection of likely invariants
http://plse.cs.washington.edu/daikon/
Other
214 stars 54 forks source link

NoClassDefFoundError when executing Java program with DynComp #532

Closed degrigis closed 5 months ago

degrigis commented 7 months ago

==== INFO ====

JAVA VERSION:

openjdk version "11.0.19" 2023-04-18
OpenJDK Runtime Environment (build 11.0.19+7-post-Ubuntu-0ubuntu118.04.1)
OpenJDK 64-Bit Server VM (build 11.0.19+7-post-Ubuntu-0ubuntu118.04.1, mixed mode, sharing)

DAIKON VERSION:

latest commit

==============

Hello,

I have a quick question/issue: I'm trying to generate (using DynComp) the .decl file of a program that makes use of the following imports:

import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpExchange;

however, when trying to do:

java -cp .:$DAIKONDIR/daikon.jar  daikon.DynComp SimpleWebServer

I get the following error:

Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/net/httpserver/HttpServer
    at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
    at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3166)
    at java.base/java.lang.Class.getDeclaredMethod(Class.java:2473)
    at daikon.chicory.MethodInfo.initViaReflection(MethodInfo.java:155)
    at daikon.chicory.ClassInfo.initViaReflection(ClassInfo.java:86)
    at daikon.dcomp.DCRuntime.enter(DCRuntime.java:1226)
    at SimpleWebServer.main(SimpleWebServer.java)

The .class file for HttpServer is in /usr/lib/jvm/java-11-openjdk-amd64/jmods/jdk.httpserver.jmod.

I'm generating the JAR of the program in the following way:

javac -g SimpleWebServer.java
jar cfe SimpleWebServer.jar SimpleWebServer Manifest.txt *.class

Am I doing something wrong or is this a known issue?

This is the code of the SimpleWebServer

import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpExchange;

import java.net.URL;
import java.security.CodeSource;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;

public class SimpleWebServer {

    public static void main(String[] args) throws IOException {

        System.out.println(System.getProperty("java.class.path"));

        Class klass = HttpServer.class;
        URL location = klass.getResource('/' + klass.getName().replace('.', '/') + ".class");

        System.out.println(location.toString());

        CodeSource src = klass.getProtectionDomain().getCodeSource();
        System.out.println(src.toString());

        if (src != null) {
            URL jar = src.getLocation();
            System.out.println(jar.toString());
        }

        // Create an HTTP server that listens on port 8080
        HttpServer server = HttpServer.create(new InetSocketAddress(9090), 0);

        // Create a context for the "/hello" path and set the handler
        server.createContext("/hello", new HelloHandler());

        // Start the server
        server.start();

        System.out.println("Server is running on port 9090. Open your browser and visit http://localhost:9090/hello");

        // Add a shutdown hook to gracefully stop the server when the program is terminated
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            System.out.println("Stopping server...");
            server.stop(0);
            System.out.println("Server stopped.");
        }));
    }

    // Custom handler for the "/hello" path
    static class HelloHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange httpExchange) throws IOException {
            // Prepare the response message
            String response = "Hello, World!";

            // Set the response headers
            httpExchange.getResponseHeaders().set("Content-Type", "text/plain");
            httpExchange.sendResponseHeaders(200, response.length());

            // Get the output stream and write the response
            try (OutputStream os = httpExchange.getResponseBody()) {
                os.write(response.getBytes());
            }
        }
    }
}

Thanks!

markro49 commented 7 months ago

I have reproduced your error and will investigate further.

markro49 commented 5 months ago

Needed to modify how we set BootClasspath. FIxed with https://github.com/codespecs/daikon/pull/534.