What is Judge0

Judge0 is an open-source online code execution and grading system that allows you to run code in more than 50 programming languages.

The Judge0 grading server is a component of the Judge0 system that is responsible for executing and evaluating the submitted code. When a user submits their code, the grading server compiles and runs it on a secure and isolated environment to ensure that it does not harm the system or other users. The grading server then checks the output of the code against the expected output to determine whether the submission is correct.

How it works

Sending a submission

To send a submission to the grading server, you need to make a POST request to the /submissions endpoint. The request body should contain at least the following fields:

  • source_code - the source code of the submission
  • language_id - the ID of the programming language that the source code is written in

Other options that may be helpful are:

  • stdin - the input that should be sent to the program
  • expected_output - the expected output of the program
  • cpu_time_limit - the maximum amount of time that the program can run for

It will return a JSON object with the most notable field being:

  • token - the token that can be used to get the status of the submission

Example of how it would look sending a submission to the server from JavaScript:

// btoa is what allows us to encode the code in base64
YOUR_BASE64_ENCODED_CODE = btoa(code);

const API_URL = "https://judge0.nighthawkcodingsociety.com/";

const headers = {
  "content-type": "application/json",
};

const data = {
  source_code: code,
  language_id: 62, // Java language ID
  stdin: "",
};

fetch(API_URL + "submissions", {
  method: "POST",
  headers: headers,
  mode: "cors",
  cache: "no-cache",
  body: JSON.stringify(data),
})
  .then((response) => response.text())
  .then((data) => {
    // handle the data output, use this token to get the status of the submission
    const token = data.token;
    /*

    this is where the interval code goes, see below

    */
  })
  .catch((error) => {
    // error handling
  });

Getting the status of a submission

To get the status of a submission, you need to make a GET request to the /submissions/:token endpoint. The :token part of the URL should be replaced with the token that was returned when the submission was sent.

// We need an interval because the submission needs to keep polling the server to see if it has compiled yet
let interval = setInterval(() => {
  fetch(API_URL + `submissions/${submissionId}?base64_encoded=true`, {
    headers: headers,
  })
    .then((response) => response.json())
    .then((data) => {
      if (data.status.id <= 2) {
        // Status is either "queued" or "processing"
        console.log("Status: " + data.status.description);
      } else {
        // Status is "completed"
        clearInterval(interval);
        const output = atob(data.stdout);
        console.log("Output: " + output);
      }
    })
    .catch((error) => {
      // Status is usually 'Compilation Error' or 'Runtime Error'
      console.error(error);
    });
}, 1000);

Backend Implementation

If you decide to do backend implementation in Java, then we recommend using the rapidAPI suggestions for creating a submission and getting the status of a submission. Simply replace the url of the rapid api with the url of your judge0 server, and you don’t need the rapidAPI keys and headers.

CORS Issues

You may also run into an issue with CORS when using the server from a different domain. To fix this, we recommend adding this to your java files.

SecurityConfig.java

.cors().and()
.headers()
    .addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Credentials", "true"))
    .addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-ExposedHeaders", "https://YOUR_FRONTEND_USERNAME.github.io", "Authorization"))
    .addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Headers", "Content-Type", "Authorization", "x-csrf-token"))
    .addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-MaxAge", "600"))
    .addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Methods", "POST", "GET", "OPTIONS", "HEAD"))
    .addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Origin", "https://YOUR_FRONTEND_USERNAME.github.io"))

MvcConfig.java

@Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedOrigins("https://YOUR_FRONTEND_USERNAME.github.io");
    }

Nginx Config File on Server

if ($request_method = OPTIONS ) {
    add_header "Access-Control-Allow-Credentials"  "true";
    add_header "Access-Control-Allow-Origin"  "https://YOUR_FRONTEND_USERNAME.github.io";
    add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
    add_header "Access-Control-Allow-MaxAge"  600;
    add_header "Access-Control-Allow-Headers" "Content-Type, Authorization, x-csrf-token";
    return 200;
}