Ant <JAVAC> задача бросает StackOverflowException

голоса
4

Я пытаюсь собрать более 100 Java классов из различных пакетов из чистой директории (не постепенные компилирует), используя следующий муравей задачу:

<target name=-main-src-depend>
    <depend srcdir=${src.dir} 
            destdir=${bin.dir} 
            cache=${cache.dir}
            closure=true/>
</target>   

<target name=compile depends=-main-src-depend
        description=Compiles the project.>

    <echo>Compiling</echo>

    <javac  target=${javac.target}
            source=${javac.source}
            debug=${javac.debug}
            srcdir=${src.dir}
            destdir=${bin.dir}>
        <classpath>
            <path refid=runtime.classpath/>
            <path refid=compile.classpath/>
        </classpath>
    </javac>
</target>

Тем не менее, первый раз , когда я выполнить задачу компиляции я всегда получаю StackOverflowException. Если я снова запустить задачу компилятор делает инкрементную сборку и все работает отлично. Это нежелательно , так как мы используем CruiseControl , чтобы сделать автоматическую ежедневную сборку , и это приводит к возникновению ложных отказов сборки.

Как быстро и грязное решение, которое я создал 2 отдельных задачи, составление частей проекта в каждом. Я действительно не думаю, что это решение будет проводить в несколько классов добавлены в будущем, и я не хочу, чтобы добавлять новые задачи, компилировать каждый раз, когда мы попали в «компилировать предел».

Задан 19/08/2008 в 21:53
источник пользователем
На других языках...                            


6 ответов

голоса
4

Это будет приятно знать; что может вызвать или вызывает StackOverflowError во время компиляции Java кода?

Вполне вероятно , что оценка длинного выражения в файле Java потребляет много памяти и потому , что это делается в сочетании с компиляцией других классов, VM просто бежит из стека. Ваш сгенерированный класс, возможно , выдвигая юридические ограничения на его содержание. Смотрите главу 4.10 Ограничения виртуальной машины Java в The Java Virtual Machine Specification, Second Edition .

Fix 1: реорганизовать класс

Поскольку ваш класс генерируется, это не может быть вариантом. Тем не менее, стоит обратить внимание на вариантах вашего инструмента генерации класса предлагает, чтобы увидеть, если он может производить что-то менее хлопотно.

Закрепить 2: увеличить размер стека

Я думаю , что Кирон имеет одно решение , когда он упоминает -Xss аргумента. Javac принимает ряд нестандартных аргументов , которые будут различаться между версиями и поставщиками компиляторов.

Мой компилятор:

$ javac -version
javac 1.6.0_05

Для того, чтобы перечислить все варианты для этого, я хотел бы использовать эти команды:

javac -help
javac -X
javac -J-X

Я думаю , что предел стека для JAVAC является 512Кб по умолчанию. Вы можете увеличить размер стека для этого компилятора 10Мб с помощью следующей команды:

javac -J-Xss10M Foo.java

Вы можете быть в состоянии передать это в Ant файл с compilerarg элемент вложен в вашей JAVAC задаче.

<javac srcdir="gen" destdir="gen-bin" debug="on" fork="true">
    <compilerarg value="-J-Xss10M" />
</javac>
Ответил 21/08/2008 в 13:58
источник пользователем

голоса
1
  <javac srcdir="gen" destdir="gen-bin" debug="on" fork="true">
      <compilerarg value="-J-Xss10M" />
    </javac>

из комментария выше неверно. Вам нужно пространство между -J и -X, например , так:

<javac srcdir="gen" destdir="gen-bin" debug="on" fork="true">
    <compilerarg value="-J -Xss10M" />
</javac>

чтобы избежать следующее сообщение об ошибке:

 [javac] 
[javac] The ' characters around the executable and arguments are
[javac] not part of the command.
[javac] Files to be compiled:

... [Javac] Javac: неверный флаг: -J-Xss1m [Javac] Использование: Javac

Ответил 25/06/2009 в 05:50
источник пользователем

голоса
1

Попробуйте добавить некоторые вариации этих атрибутов к Ant javacцелевой строки:

memoryinitialsize="256M" memorymaximumsize="1024M"

Вы также можете попробовать fork="true", не уверен , если это позволяет установить значения для стека и кучи (ака -Xm1024), но это может помочь (если она будет работать из командной строки, но не в Ant).

[Изменить]: Добавлено звено - javacзадача страницы , казалось бы предположить , что параметры выше требуют , чтобы вы также установить fork="true".

Ответил 19/08/2008 в 22:05
источник пользователем

голоса
1

Происходит ли это при выполнении команды JAVAC из командной строки? Вы можете попробовать вилочный атрибут.

Ответил 19/08/2008 в 22:04
источник пользователем

голоса
0

Вот что я нашел. После отправки сообщения на мой вопрос , я пошел дальше и изменил задачу компиляции с атрибутами fork="true", memoryinitialsize="256m"и memorymaximumsize="1024m"(найденной сегодня , что это было предложено Kieron и jmanning2k, спасибо за ваше время). Это не решает проблему , тем не менее.

Я решил начать удаление классов из исходного дерева , чтобы увидеть , если можно было точно определить проблему. Оказывается, у нас была служба клиентского класса Web для оси 1.4 , которая автоматически генерируется из файла WSDL. Теперь этот класс монстр (как в Франкенштейна), он имеет 167 членов на местах (все они типа String), 167 геттер / пар инкубационные (1 для каждого поля), конструктор , который принимает все 167 полей в качестве параметров, А.Н. составляет метод , который сравнивает все 167 полей странным образом. Для каждого поля сравнение выглядит следующим образом :

(this.A == null && other.getA() == null) || (this.A != null && this.A.equals(other.getA()))

Результат этого сравнения является «операцией AND» (&&) с результатом сравнения следующего поля, и так далее. Класс идет с методом Hashcode, который также использует все поля, некоторые методы сериализации пользовательских XML и методом, который возвращает ось специфичного объекта метаданных, описывающий класс, и также использует все элементы поля.

Этот класс никогда не изменяется, так что я просто поставить скомпилированную версию в пути к классам приложений и проект компилируется без проблем.

Теперь, я знаю, что удаление этого одного исходного файла решить эту проблему. Тем не менее, я не имею ни малейшего понятия, почему именно этот класс вызвал проблему. Это будет приятно знать; что может вызвать или вызывает StackOverflowError во время компиляции Java кода? Я думаю, что я выложу этот вопрос.

Для тех, кто заинтересован:

  • Windows XP SP2
  • SUN в JDK 1.4.2_17
  • Ant 1.7.0
Ответил 20/08/2008 в 15:23
источник пользователем

голоса
0

Это довольно странно, 100 классов на самом деле не так уж много. Что такое компилятор делает , когда стек переполняется? Есть полезные трассировки стеки сгенерированы? Что произойдет , если вы запустите javacнепосредственно в командной строке вместо Копания муравья?

Одним из возможных способов заключается в просто увеличить размер стека , используя -Xssаргумент JVM; либо к JVM подряд antили установив fork="true"и <compilerarg>на <javac>задачу. На самом деле теперь, когда я думаю об этом, делает проблему уйти просто положить в fork="true"?

Ответил 19/08/2008 в 22:21
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more