antlr4 Jar имеет повторяющиеся классы в разных пакетах — не знаю, на которые ссылается внутренний код

#classpath #antlr4

#classpath #antlr4

Вопрос:

Я использую antlr4.3 (полный) jar. Он имеет много дубликатов в пакетах org.antlr.runtime и org.antlr.v4.runtime.

В коде, когда я явно использую ‘v4.runtime’ — во время выполнения classpath выбирает ‘runtime’. Поэтому я извлек jar и воссоздал его без org.antlr.runtime.

Но, по-видимому, некоторые классы, такие как RecognitionException, теперь не найдены.

Как я должен решить это, кроме:

Взрыв последней версии Jar и указание org.antlr.v4.runtime ПЕРЕД org.antlr.runtime, чтобы дублирующий класс был взят из v4.runtime, и если в нем его нет, он будет искать org.antlr.runtime …??

Чтобы добавить к вышесказанному, вот фрагмент кода, который создает проблему: банки находятся в пути к классу.

 import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.ANTLRInputStream;

public class AntlrMain {

  public static void main(String[] args) {
    System.out.println("Start Hello World");
    try {
      InputStream is = new FileInputStream(
          "/home/ecworkspace/antlrCentral/DSL/mydev.dsl");
      org.antlr.runANTLRInputStream input = new ANTLRInputStream(is);
      org.antlr.v4.runtime.CharStream cs = (org.antlr.v4.runtime.CharStream) input;
      VCFGLexer lexer = new VCFGLexer(cs);
  
  1. Изначально в классе ANtlrMain я не использовал явный
    org.antlr.v4.runtime.; но это не удалось во время выполнения, с 'CharStream not found' .
  2. Затем я изменил, чтобы включить полный путь к классу
  3. Затем изменил ANTLR4 Jar на ‘exclude’ org.antlr.runtime (у него есть org.antlr.v4.runtime). Именно тогда 'RecognitionException not found' произошла ошибка.

Грамматика, кстати, компилируется нормально, генерируя все мои VCFG*.java and tokens классы, где VCFG — это имя грамматики.

ОБНОВЛЕНИЕ 1

Следуя предложениям от all — я удалил свой ответ на свои собственные вопросы и добавил его к этим исходным вопросам.

В antlr-4.2-complete.jar , Я вижу:

 /tmp/x/ $ jar -xf antlr-4.2-complete.jar 

/tmp/x/ $ ls org/antlr
runtime  stringtemplate  v4

/tmp/x/ $ ls org/antlr/v4
analysis  codegen  parse    semantics  Tool$1UndefChecker.class  Tool$OptionArgType.class
automata  misc     runtime  tool       Tool.class                Tool$Option.class

/tmp/x/ $ ## The 2 runtimes above: org.antlr.runtime and org.antlr.v4.runtime
/tmp/x/ $ ## which to use where, along with same-name classes in 
/tmp/x/ $ ##  org.antlr and org.antlr.v4
  

Итак, в build.xml , я использую вышеуказанную банку для:
`

  • java -jar antlr-4.2-полная грамматика.g4 => компилирует и выдает мне VCFG *.java и VCFG *.tokens
  • javac -cp «antlr-4.2-complete-jar» VCFG *.java => Завершается успешно.У меня есть коллекция VCFG * .class .
  • Затем я компилирую свой код AntlrMain.java (который использует AntlrInputStream и т.д.), снова с вышеупомянутым antlr jar и некоторыми сторонними Jar
    (ведение журнала, commons) => успешно.
  • Наконец, ЗАПУСК java -cp "antlr-4.2-complete.jar:log4j.jar" -jar
    myJar
    => ЗАВЕРШАЕТСЯ с ОШИБКОЙ при ‘CharStream’ не найден.

ОБНОВЛЕНИЕ 2

Добавление, основанное на вашем ответе.

Я только недавно начал публиковать вопросы по Stackoverflow. Поэтому приветствуются указания о том, отвечать ли на мой вопрос, чтобы предоставить дополнительную информацию, или комментировать ответ и т. Д.

 -cp <3rd-party> is -cp "log4j.jar:commonsLang.jar".  
  

Под -cp «выше-jar» я имел в виду -cp «antlr-4.2-complete.jar .

И если я не упомянул об этом, это оплошность — у меня для каждой команды java и javac включены antlr-4.2-complete.jar . НО я вижу, что вы указываете antlr-runtime-4.2.jar . Таким образом, существуют отдельные банки antlr-runtime jar и antlr-complete jar.

В 4 шагах ниже (я оставляю out -cp для удобства, но включаю antlr-4.2-complete.jar для «каждого» шага.

Я считаю, что я должен использовать antlr-run-time и antlr-complete jar на разных этапах:

 1 (java MyGrammar.java) 
2 (javac MyGrammar*.java) 
3. javac MyOwnCode.java 
4. Run myCode (java MyCode) ...
  

какую из двух банок antlr (runtime и complete; и их версии) я должен затем использовать на каждом из вышеуказанных 4 шагов?

Ответ №1:

Файл jar не содержит повторяющихся классов. Часть генерации кода инструмента ANTLR 4.3 основана на библиотеке времени выполнения ANTLR 3.5.2, которая включена в «полный» файл jar. Хотя некоторые классы имеют те же имена, что и классы в ANTLR 4, они не являются дубликатами и не могут использоваться взаимозаменяемо.

Комментарии:

1. @user3213604 Вместо того, чтобы добавлять свою правку в качестве «ответа», вам следует отредактировать исходный вопрос, чтобы более четко объяснить проблему. Кроме того, что такое -cp ":<3rd-party>" ? Нет никаких указаний на то, что это такое, и вы также не включили ANTLR jar в classpath при запуске jar, поэтому очевидно, что классы, которые он содержит, не будут найдены. Я ожидал увидеть либо -cp "<above-jar>" или -cp "antlr-runtime-4.2.jar" при запуске вашего jar.

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

3. поскольку вы упомянули, что «библиотека времени выполнения» включена в «полный» jar. Должен ли я разделить полный jar, чтобы я мог использовать одну часть для генерации * .java и скомпилировать ее вместе со своим кодом …. и использовать другую часть (часть времени выполнения) в пути к классам во время выполнения (java -cp «runtime-something.jar » mycode)? или две части загружаются отдельно — jar во время компиляции и во время выполнения; вместо загрузки одного antlr-4.2-complete.jar ?

Ответ №2:

@280Z28 / Sam:

Я огорчен, но должен признать, что самый простой ответ чаще всего правильный. Я потратил время на доработку JAR, создание из него нескольких файлов JAR, включая один для компиляции, один для запуска и так далее. и так далее.

Ответ кратко объясняется в ANT build.xml фрагмент кода ниже: где я создаю «окончательный» производственный файл JAR, который является единственным JAR, включенным при выполнении моей основной программы:

 <jar destfile="${p_productionJar}">
      <fileset dir="${p_buildDir}" casesensitive="yes">
        <include name="**/*.class"/>
      </fileset>
      <zipfileset includes="**/*.class" src="${p_genCodeJar}"/>
       <!-- How did I miss including p_antlrJar earlier?? -->
      <zipfileset includes="**/*.class" src="${p_antlrJar}"/>
      <zipfileset includes="**/*.class" src="${p_jschJar}"/>
      <zipfileset includes="**/*.class" src="${p_log4jJar}"/>
      <zipfileset includes="**/*.class" src="${p_commonslangJar}"/>
      <manifest>
        <attribute name="Main-Class" value="AntlrMain"/>
        .....
  

В рабочей Jar отсутствовал $ {p_antlrJar} => который antlr-4.3-complete.jar !!!!
Вы упомянули об этом в своем ответе… но это была довольно глупая ошибка, и я не думал, что я это сделал…
Спасибо.