neděle 10. dubna 2005

Ant, java.io.IOException: CreateProcess a zatrolená konzole

Nemám ve zvyku každou chybu/vlastnost znamenající můj vlastní neúspěch svalovat na někoho jiného, ale jsou věci, které mě docela dopalují. Víte o tom, že Command prompt (Cmd. exe) command-line má omezenou délku vstupu? Pro Windows XP je to 8191 a pro Windows 2000 je to 2047. Už se mi minimálně dvakrát stalo, že mě 2047 znaků pěkně vypeklo.

Poprvé jsem na to narazil v souvislosti s naším aplikačním serverem, kde se nastavovala nechutně dlouhá classpath. Po druhé mě to vypeklo včera, ale narozdíl od prvního případu, odhalit, že za to může omezení délky vstupu zabralo nějaký čas a nervy.

Javadoc na scéně

Ant je pořádně mocný kouzelník a mezi jeho kouzla patří task Javadoc, který vygeneruje dokumentaci ze zdrojových souborů, samozřejmě pokud jí píšete. Včera jsem potřeboval velice nutně vygenerovat právě dokumentaci k API.

 
<target name="javadoc" description="Generates JavaDoc from source files">
   <javadoc
           destdir="${javadoc.dir}"
           author="true"
           version="true"
           use="true"          
    >
     <fileset dir="${src.dir}" >
       <include name="**/*.java" />       
     </fileset> 
   </javadoc>
</target>
 

Bohužel jakékoliv snahy o spuštení tohoto tasku končily (Windows 2000) s výsledkem BUILD FAILED, hláškou failed:java.io.IOException: CreateProcess:" a pěkně dlouhým stack tracem začínajícím na java.lang.Win32Process.create(Native Method). Samozřejmě na mém počítači s Windows XP ten task proběhnul. V tu chvíle jsem samozřejmě zkusil různé verze Antu a Javy, ale nic nepomohlo.

Dneska ráno jsem se rozhodnul, že tomu problému prostě přijdu na kloub. Začal jsem u přítele Googla, který mi po pár otázkách dokázal, že tenhle problém, jako obvykle, mělo plno dalších nebožáků. Celý problém je v tom, že ANT volá javadoc.exe, který se stará o generování dokumentace, předání argumentů je realizováno přes příkazovou řádku. Pak se neni čemu divit, že příkaz lehce přesáhne 2047 znaků.

Naštěstí jsem si vygooglil i řešení, task Javadoc totiž podporuje kouzelný atribut useexternalfile.

indicates whether the sourcefile name specified in srcfiles or as nested source elements should be written to a temporary file to make the command line shorter. Also applies to the package names specified via the packagenames attribute or nested package elements. (yes | no). Default is no.

Za řešení problému jsem vděčen těmto diskusím, 1, 2 a 3