Java is difficult to deal with in an automatic way. It is probably most preferable to use Oracle (previously Sun) 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.
With the default configuration, submitted programs are run within a minimal chroot environment. For this the programs have to be statically linked, because they do not have access to shared libraries.
For most languages compilers support this, but for Java, this is a bit problematic. The Oracle Java compiler `javac' is not a real compiler: a bytecode interpreter `java' is needed to run the binaries and thus this cannot simply run in a chroot environment.
There are some options to support Java as a language:
bin/dj_make_chroot
creates one from Debian GNU/Linux
sources; run that script without arguments for basic usage
information. Next, edit the script lib/judge/chroot-startstop.sh
and adapt it to work with your local system and uncomment the
script in etc/judgehost-config.php
.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.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. No guarantees about system security
can be made when running a contest with chroot disabled.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 judge/compile_java_javac.sh
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
Error occurred during initialization of VM Could not reserve enough space for object heap
MEMRESERVED
variable in judge/compile_java.sh
and
check that the configuration variable memory-limit
is set
larger than MEMRESERVED
.
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 compile_java_javac.sh
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
compile_java_javac_detect.sh
, 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 and two similar
scripts compile_java_gcj.sh
and
compile_java_gcj_detect.sh
are available.
When using the GNU GCJ compiler 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).
To filter these warnings, take a look at
judge/compile_java_gcjmod.sh
and replace or symlink
judge/compile_java.sh
by/to this file.
This error can have various causes. First of all: check the
submit.log
file for more complete error messages.
Assuming the default configuration where submit_copy.sh uses `scp', we have found that shell initialisation scripts might contain statements which generate errors: scp runs the user's default shell when copying submission files and when the shell dies (e.g. because of not having a terminal), the copying fails.
Another cause might be that you do not have automatic access to the team's account (e.g. using ssh keys).
Using the mono compiler and runtime for C# gives rise to similar
problems as with Java. Although the C# language has been added to
DOMjudge, there's no support yet to run it within a chroot
environment. So in that case, USE_CHROOT
must be disabled.
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 154This 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.
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.
Compiling failed with exitcode 255, compiler output: /home/domjudge/system/bin/runguard: root privileges not droppedWhen 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.