Next Previous Contents

8. Common problems and their solutions

8.1 Java compilers

Java is difficult to deal with in an automatic way. It is probably most preferable to use OpenJDK or Oracle Java, because that's the version contestants will be used to. The GNU Compiler for Java (GCJ) is easier to deal with but may lack some features.

The recommended way of using Java is by setting up the chroot (see section creating a chroot environment), but you can also choose one of the alternatives as described below.

  1. As an alternative the gcj compiler from GNU can be used instead of Oracle's version. This one generates true machine code and can link statically. However a few function calls cannot be linked statically (see `GCJ compiler warnings' in this FAQ). Secondly, the static library libgcj.a doesn't seem to be included in all GNU/Linux distributions: at least not in RedHat Enterprise Linux 4.
  2. One can disable the chroot environment in etc/judgehost-config.php by disabling USE_CHROOT. Disabling the chroot environment removes this layer of security against submissions that attempt to cheat, but it is a simple solution to getting Java to work, for demo or testing purposes. Note: no guarantees about system security can be made when running a contest with chroot disabled!

8.2 The Java virtual machine (jvm) and memory limits

DOMjudge imposes memory limits on submitted solutions. These limits are imposed before the compiled submissions are started. On the other hand, the Java virtual machine is started via a compile-time generated script which is run as a wrapper around the program. This means that the memory limits imposed by DOMjudge are for the jvm and the running program within it. As the jvm uses approximately 300MB, this reduces the limit by this significant amount. See the java_javac and java_javac_detect compile executable scripts for the implementation details.

If you see error messages of the form


Error occurred during initialization of VM
java.lang.OutOfMemoryError: unable to create new native thread

or
Error occurred during initialization of VM
Could not reserve enough space for object heap

Then the problem is probably that the jvm needs more memory than what is reserved by the Java compile script. You should try to increase the MEMRESERVED variable in the java compile executable and check that the configuration variable memory limit is set larger than MEMRESERVED. If that does not help, you should try to increase the configuration variable process limit (since the JVM uses a lot of processes for garbage collection).

Note that (especially on x86_64 machines) the jvm seems to preallocate huge amounts of memory, up to 2 GB! This is not actually all used, but the memory restriction in DOMjudge will flag it as such, unless Linux cgroups are enabled, then the actual memory used is measured. Thus, we strongly recommend using Linux cgroups when using the Oracle jvm.

8.3 Java class naming

Java requires a specific naming of the main class. When declaring the main class public, the filename must match the class name. Therefore one should not declare the main class public; from experience however, many teams do so. Secondly, the Java compiler generates a bytecode file depending on the class name. There are two ways to handle this.

The simplest Java compile script java_javac requires the main class to be named Main with method


public static void main(String args[])

The alternative (and default) is to use the script java_javac_detect, which automatically detects the main class and even corrects the source filename when it is declared public.

When using the GNU gcj compiler, the same holds for the java_gcj script as for java_javac.

8.4 GCJ compiler warnings

When using the GNU GCJ compiler script java_gcj for compiling Java sources, it can give a whole lot of warning messages of the form

/usr/lib/gcc-lib/i386-linux/3.2.3/libgcj.a(gc_dlopen.o)(.text+0xbc):
In function `GC_dlopen': Using 'dlopen' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking

These are generated because you are trying to compile statically linked sources, but some functions can not be static, e.g. the `dlopen' function above. These are warnings and can be safely ignored, because under normal programming contest conditions people are not allowed to use these functions anyway (and they are not accessible within the chroot-ed environment the program is run in).

8.5 Memory limit errors in the web interface

When uploading large testdata files, one can run into an error in the jury web interface of the form:

Fatal error: Allowed memory size of XX bytes exhausted (tried to
allocate YY bytes) in /home/domjudge/system/lib/lib.database.php
on line 154
This means that the PHP engine has run out of memory. The solution is to raise the memory limits for PHP. This can be done by either editing etc/apache.conf and raising the memory_limit, upload_max_filesize and post_max_size values to well above the size of your largest testcase. You can change these parameters under the jury directory or by directly editing the global Apache or php.ini configuration. Note also that max_file_uploads must be larger than the maximum number of testcases per problem to be able to upload and edit these in the web interface.

The optional PHP Suhosin module may also impose additional limits; check your error logging to see if these are triggered. You may also need to raise MySQL's max_allowed_packet parameter in /etc/mysql/my.cnf on both server and client.

8.6 Compiler errors: `runguard: root privileges not dropped'

Compiling failed with exitcode 255, compiler output:
/home/domjudge/system/bin/runguard: root privileges not dropped
When the above error occurs on submitting any source, this indicates that you are running the judgedaemon as root user. You should not run any part of DOMjudge as root; the parts that require it will gain root by themselves through sudo. Either run it as yourself or, probably better, create dedicated a user domjudge under which to install and run everything.

Also do not confuse this with the domjudge-run user: this is a special user to run submissions as and should also not be used to run normal DOMjudge processes; this user is only for internal use.

8.7 found processes still running ... apport

error: found processes still running as 'domjudge-run', check manually:
2342 apport
The above error occurs on submitting segmentation fault solutions if you have apport installed (which is default on Ubuntu). Disable or uninstall the apport daemon on all judgehosts.

8.8 Enforcement of time limits

Time limits within DOMjudge are enforced primarily in CPU time, and secondly a more lax wall clock time limit is used to make sure that submissions cannot idle and hog judgedaemons. The way that time limits are calculated and passed through the system involves a number of steps, so documented here.

Time limits are set per problem in seconds. Each language in turn may define a time factor (defaulting to 1) that multiplies it to get a specific time limit for that problem/language combination. This is the soft timelimit. The configuration setting timelimit overshoot is then used to calculate a hard timelimit. This overshoot can be specified in terms of an absolute and relative margin.

The soft:hard timelimit pair is passed to testcase_run.sh and then on to runguard as both wall clock and CPU limit. Since the CPU option is passed second, this one is used by runguard when reporting whether the soft, actual timelimit has been surpassed. The submitted program gets killed when either the hard wall clock or CPU time has passed.


Next Previous Contents