1
votes

I am using antlr4.3 (complete) jar. It has many duplicates in org.antlr.runtime and org.antlr.v4.runtime packages.

In code when I explicitly use 'v4.runtime' - at runtime, classpath picks up 'runtime'. So I extracted the jar and recreated it without org.antlr.runtime.

But apparently some classes like RecognitionException is now not found.

How should I resolve this other than:

Exploding the latest Jar and specifying org.antlr.v4.runtime BEFORE org.antlr.runtime so that a duplicate class will be picked up from v4.runtime, and if there isn't one in it, it will look at org.antlr.runtime...??

To add to the above, here's the code snippet which gives a problem: the jars are in the classpath.

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. Initially in the ANtlrMain class, I wasn't using explicit org.antlr.v4.runtime.; but that failed at runtime, with 'CharStream not found'.
  2. Then I changed to include full path of the class
  3. Then changed the ANTLR4 Jar to 'exclude' org.antlr.runtime (it has org.antlr.v4.runtime). That's when the 'RecognitionException not found' error occurred.

The grammar by the way, compiles OK, generating all my VCFG*.java and tokens classes, where VCFG is the grammar name.

UPDATE 1

Keeping in line with suggestions from all - I removed my answer to my own questions and adding it to this original questions.

In antlr-4.2-complete.jar, I see:

/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

So, in build.xml, I use above jar to: `

  • java -jar antlr-4.2-complete grammar.g4 => compiles and gives me VCFG*.java and VCFG*.tokens
  • javac -cp "antlr-4.2-complete-jar" VCFG*.java => Succeeds. I have the VCFG*.class collection.
  • Then I compile my code AntlrMain.java (which uses AntlrInputStream etc.), again with the above antlr jar and some 3rd-party Jars
    (logging, commons) => successfully.
  • Finally the RUN of java -cp "antlr-4.2-complete.jar:log4j.jar" -jar myJar => FAILS on 'CharStream' not found.

UPDATE 2

Adding, based on your response.

I have only recently started posting questions on Stackoverflow. So pointers about whether to respond to my question to provide more info, or to comment to a reply etc. are welcome.

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

By -cp "above-jar" I meant -cp "antlr-4.2-complete.jar.

And if I have not mentioned it, it is an oversight - I have, for every 'java' and 'javac commands, included antlr-4.2-complete.jar. BUT I see you indicating antlr-runtime-4.2.jar. So there ARE separate antlr-runtime jar and antlr-complete jars.

In the 4 steps below (I am leaving out -cp for convenience, but am including antlr-4.2-complete.jar for 'every' step.

I believe, I should be using the antlr-run-time and antlr-complete jars at different steps:

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

which of the two antlr JARs (runtime and complete; and their versions) should I then use, at each of the above 4 steps?

2

2 Answers

3
votes

The jar file does not contain duplicate classes. The code generation portion of the ANTLR 4.3 Tool relies on the ANTLR 3.5.2 Runtime library, which is included in the "complete" jar file. While some of the classes have the same name as classes in ANTLR 4, they are not duplicates and cannot be used interchangeably.

0
votes

@280Z28 / Sam:

I am mortified, but have to admit the simplest answer is most often the correct. I spent time fleshing out the JAR, making multiple JAR files out of it, include one for compile, one for run and on and on.

The answer is succinctly explain in the ANT build.xml code snippet below: where I produce the 'final' production JAR file, which is the only JAR then included while executing my Main program:

<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"/>
        .....

The production Jar was missing ${p_antlrJar} => which is antlr-4.3-complete.jar!!!! You did mention this in your answer... but it was a pretty silly mistake to do, and didn't think I had done it... Thank you.