Antlr4 maven plugin cannot find grammar files in different directories - maven

I'm using the antlr4 maven plug-in to build my maven project which uses antlr4:
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>4.0</version>
I started with one grammar file and got my pom.xml set-up and everything was building nicely.
Then I decided to split my grammar into logical parts and therefore used several grammar files but in different directories (so the generated code would be put into separate packages) but still all under the same root src/main/antlr4 directory.
I use the import statement in my "top" level grammar file to import the other required files.
But now maven gives me the following error when trying to build:
[ERROR] Message{errorType=CANNOT_FIND_IMPORTED_GRAMMAR
Why can't antlr find the other files that I am importing?
thanks,
Ryan.

I had the same problem and solved with the following configuration:
<libDirectory>${basedir}/src/main/antlr4/yourGrammarDirectory</libDirectory>
Look here: How to import grammar in Antlr4 to build with maven

For the ANTLR 4.0 release, no testing was performed on imports across multiple directories.
Due to the limited benefits (IMO) provided by the current grammar import mechanism, this is currently a very low priority feature. Currently, sharing grammar files by using imports will not allow you to share code for the generated parsers or the parse trees they produce. I've been using ANTLR for years on dozens of products (including commercial releases), and not once have I found composite grammars to provide more benefits than trouble. (Note that I'm talking about the import statement here. Separating lexer and parser grammars into separate files in the same directory is frequently beneficial and my preferred way to work.)

Related

Is there a best practice to remove old dependencies from maven pom?

My company is trying to get our team off Junit3 (and 4) and onto Junit5.
Our pom file has dependencies for Junit3, 4 and 5 already.
I'd like to somehow mark Junit3 and 4 as "deprecated at my company" to give anyone who is trying to use these older versions a visual clue in the UI that we want to stop using these.
Is there a method to mark some dependency in Maven as "deprected at my company?"
Short of that, I suppose we could write a checkstyle rule or some other static analysis, but I really think it would be less obtrusive to have the visual indicator (like javadocs or #Deprecated annotations).
Thoughts or addins that would do this?
If IDE matters, we have IntelliJ, Visual Studio code and a handful of stalwarts still on vim.
You can use the maven-enforcer-plugin to enforce not using those libraries: http://maven.apache.org/enforcer/enforcer-rules/bannedDependencies.html
You can have the plugin configuration shared across all projects (e.g. in the parent POM).
I'd like to find a utility that doesn't fail if any instance of a banned dependency is found, only new instances.
It looks like ArchUnit may give you the flexibility you are asking for. For example, a simple test below fails if any of the classes in the analyzed packages actually use classes from the org.junit package:
package com.stackoverflow.example;
import com.tngtech.archunit.junit.AnalyzeClasses;
import com.tngtech.archunit.junit.ArchTest;
import com.tngtech.archunit.lang.ArchRule;
import com.tngtech.archunit.lang.syntax.ArchRuleDefinition;
#AnalyzeClasses(
packages = "<root package of your module>"
)
public class JUnit4UsageTest {
#ArchTest
public static final ArchRule RULE_NO_CLASSES_SHOULD_ACCESS_JUNIT4_PACKAGES =
ArchRuleDefinition.noClasses()
.should()
.dependOnClassesThat()
.resideInAPackage("org.junit");
}
The DSL provided by the ArchUnit is powerful enough to express the rules, as long as the information is preserved in the class file.
The library also provides support for the freezing arch rules - they succeed for known recorded issues, but fail for any new one.

How to build an ANTLR grammar with Gradle in a multi-platform project?

So I have been struggling all afternoon with getting some Gradle build to work for a Kotlin multiplatform project that involves an ANTLR grammar. What I'm trying to do is to have a parser generated by ANTLR from a shared grammar for both a Kotlin (or Java if that doesn't work) and JavaScript target. Based on this I'd like to write some library around the parser that can be used from the JVM and JavaScript.
So I have set up a Kotlin multi-platform project because that seemed like a nice way of killing two birds with one stone (here is a repo https://github.com/derkork/project.txt). I created a source set commonAntlr where I placed the grammar file under commonAntlr/antlr/project_txt.g4. According to the documentation of the ANTLR plugin this is how stuff should be set up. I also apply the antlr plugin at the top (here is the build.gradle.kts - https://github.com/derkork/project.txt/blob/master/build.gradle.kts).
Now I run gradle build in the hopes that the ANTLR plugin will at least try to generate some nice Java code for me from the grammar using the default settings. Alas, it does not. The ANTLR plugin does not even get started, which is what I can tell from the output. The build later fails with some obscure JavaScript problem, but that looks unrelated and I'd like to skip over it for now.
Now my Gradle-foo isn't exactly strong (I have only used it in extremely simple projects, most of my experience is in Maven), and I have the distinct feeling I'm missing something here. However the documentation of the plugin just says
To use the ANTLR plugin, include the following in your build script:
plugins {
antlr
}
Which I did. Since I get zero output, I have a feeling that I need to do a bit more for this to work. I have read a lot of the Gradle documentation up and down to find out how plugins work in general and I found that they add tasks to the build and also add some dependencies so that tasks are invoked when you try to build certain things. However I don't really understand how plugins work together with source sets and how you can tell Gradle "would you please run the generateGrammarSource task for this source set" (or if it even works like this).
So if some of the Gradle gods could enlighten me on this, this would be much appreciated :)
I have met a similar issue: https://gitlab.com/pika-lab/tuprolog/2p-in-kotlin/tree/feature/parser
My solution -- which is still a work in progress -- consists in decomposing the problem.
I reasonable solution in my opinion is to create a Kotlin/JVM project (say parser-jvm) where to put the generated Java code + any JVM specific facility, and a Kotlin/JS project where to put the generated JS code + any JS specific facility (say parser-js). The next step is to create a Kotlin/MPP (say parser-common) project whose JVM implementation depends on parser-jvm and whose JS implementation depends on parser-js.
My approach is actually working for JVM while I'm experiencing some issues for JS, which are mostly caused by this issue.
The main drawback of this approach is that some Gradle coding is required to setup ANTLR with Kotlin/JS. I already faced this problem in my build.gradle and I'm quite satisfied with the result and the overall architecture of the project. However, I believe that my proposal is far less troublesome than configuring a Kotlin/MPP project to work with ANTLR.

How to make antlr 4 runtime as an osgibundle?

I have created a eclipse plugin and converted it to maven,which needs the dependency of antlr but when the plugin execute it says it cant find the required package. Then i came to know anltr is not osgi bundle. any one please tell me how to convert the antlr jar file into an osgi bundle.? The antlr dependency must support my mvenized eclipse plugin
The main ANTLR 4 project doesn't support this (see issue #689). However, I've recently created an independent fork of the project which aims to target a number of issues related to the use of ANTLR 4 in large(r)-scale and/or performance-critical applications. One of the items I'd like to implement is using OSGi for improved runtime versioning instead of the manual mechanism currently in place. I recommend filing an issue with this fork of the project so I can include these changes as part of my initial release.
https://github.com/tunnelvisionlabs/antlr4/issues

SonarQube excluding files, directories, and generated code?

The code base I am working with has a lot of generated code. In addition, there are also some deprecated files that I would want to exclude from SonarQube analysis. I've read up the documentation and looked at some answers on here about that, but it does not help in my case.
I have a multi-module maven project. So I have multiple projects in my workspace that are all part of a large application. Say I want to exclude this file:
/home/username/workspace/com.mst.rtra.importing.message/bin/com/mst/rtra/importing/message/idl/parse/idlparser.java
I don't really know how to write this in the exclusions settings on SonarQube because of how long the filepath is. Also, what if I want to exclude another file, but from a different module, say :
/home/username/workspace/com.mst.rtra.interpreter.create/
I am confused about I should write this in the exclusions box in project settings. Should I write the absolute file path due to the multi-module nature of this project? Or is there some other convention used?
In addition, if I want to exclude generated files from analysis, I would need to put file:/generated-sources/ as I saw in another answer. However, after analysis, I can still view the analysis results of those files when I open up the project in SonarQube dashboard.
We use ant rather than maven, and an older version of the Sonar ant task at that. But what works for us is setting a sonar.exclusions property in our build.xml, which accepts wildcards for filenames. For example:
<property name="sonar.exclusions" value="**/com/ex/wsdl/asvc/*.java,**/com/ex/wsdl/bsvc/*.java"/>
That skips analyzing all the code generated from a wsdl file for two services. You ought to be able to do something similar for maven.

Maven copy resources in multi module project

My need is pretty basic but I could not find any clean answer to it: I simply need to be able to distribute a resource in a multi-module project.
Let us consider for example the LICENSE file, which I hereby assume to be the same for all modules. I prefer not to manually copy it into each and every module because the file could change over time. I also prefer not to statically link to resources (even if using relative paths) outside the project folder, because the modular structure can possibly change too.
Is there any plugin that can be used to robustly guarantee that each module is given the required file? It would be equally acceptable for such copy to be obtained by exploiting the POM of the parent project or directly performed by the super project in the modular hierarchy.
you could use the assembly and the dependency plugins.. did you stumble over that link?
http://www.sonatype.com/people/2008/04/how-to-share-resources-across-projects-in-maven/
it describes that option ..its from 2008, but maven is around for quite some time.. so I guess its more or less up to date
edit regarding comment
Another option is the maven-remote-resources-plugin.
For a more detailed example see:
http://maven.apache.org/plugins/maven-remote-resources-plugin/examples/sharing-resources.html
Since their intro speaks actually for itself, I quote (maven.apache.org)
This plugin is used to retrieve JARs of resources from remote repositories, process those resources, and incorporate them into JARs you build with Maven. A very common use-case is the need to package certain resources in a consistent way across your organization: at Apache it is required that every JAR produced contains a copy of the Apache license and a notice file that references all used software in a given project.

Resources