Building ANTLR4 source to get source jar - intellij-idea

I could download the newest ANTLR4 (antlr-4.5.3-complete.jar) from the download page (http://www.antlr.org/download.html).
Putting the jar file in the lib directory of IntelliJ project to make the jar as a dependency to see everything works fine.
I'm trying to look into the ANTLR's source code by tracing with debugger, but I can't as I don't have the source jar.
I found the source code, and an instruction to build ANTLR (
How to build ANTLR itself). However, the instruction uses bild.py that is not included in the source.
I found the bild.py from Sam Hawell's tunnelvisionlabs/antlr4, but when I copy the script and run it, I got errors:
target all
require compile
require parsers
build compile
skipping mkjar_complete
Traceback (most recent call last):
File "/Users/smcho/Downloads/antlr4-4.5.3/bilder.py", line 847, in processargs
target()
File "bild.py", line 182, in all
mkjar()
File "bild.py", line 133, in mkjar
mkjar_complete()
File "bild.py", line 80, in mkjar_complete
require(compile)
File "/Users/smcho/Downloads/antlr4-4.5.3/bilder.py", line 434, in require
raise Exception()
Exception
bild failed
What might be wrong? How to build ANTLR4 to get source jar file?

If you want to get source (and/or javadoc), you should simply use ivy. You could also use maven as you wrote, but ivy is simpler IMHO. http://mvnrepository.com/artifact/org.antlr/antlr4/4.5.3

maven is the tool to build the jar files as is described in this document: https://github.com/antlr/antlr4/blob/master/doc/building-antlr.md
mvn compile gets the compilation done.
For getting the source jar file, pom.xml should be updated.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Then mvn package will make the source jar in tool/target directory.
For the runtime jar, the target directory is runtime/Java/target.
mvn install will install the jars into local repository.
References
Generate source code jar for Maven based project

Related

Visibility of plain jar in tycho-surefire-plugin

The problem
I am faced with the following scenario:
The sources of an Eclipse test plugin (tycho packaging type eclipse-test-plugin) depend on a "plain" jar (read: non-OSGi jar). I managed to get the tests to compile and run in Eclipse, however when running Maven/Tycho from the command line, tycho-surefire-plugin fails to execute the tests because the jar is not visible at test time. This results in a java.lang.NoClassDefFoundError while attempting to load a class from the jar.
Looking at mvn -e -X output does not reveal anything significant.
My question is, how can I include the jar in the classpath of tycho-surefire-plugin when running Maven/Tycho from the command line?
Attempts
Here is everything I have tried so far:
Use <extraRequirements> as per the tycho-surefire-plugin documentation. This however fails because the jar's packaging type is jar, while <extraRequirements> expects one of the eclipse-xxx packaging types.
For a good measure I also tried
<configuration>
<dependencies>
<dependency>
<groupId>. . .</groupId>
<artifactId>. . .</artifactId>
<version>. . .</version>
<scope>system</scope>
<systemPath>path-to-the-jar</systemPath>
</dependency>
</dependencies>
</configuration>
but the packaging type is still considered to be jar.
Use <argLine> as per tycho-surefire-plugin documentation:
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-surefire-plugin</artifactId>
<configuration>
<argLine>-cp path-to-the-jar</argLine>
</configuration>
however this appears to have no effect as the java.lang.NoClassDefFoundError persists.
Include the jar in the Eclipse test plugin. The jar is present in the MANIFEST.MF
Bundle-ClassPath: the.jar
in the build.properties
bin.includes = META-INF/,\
the.jar
and in the .classpath (although this doesn't matter for tycho-surefire-plugin).
<classpathentry exported="true" kind="lib" path="the.jar"/>
tycho-surefire-plugin once again reports java.lang.NoClassDefFoundError.
Create a dedicated Eclipse plugin to house the jar. This is for the most part equivalent to 3, where the Eclipse test plugin simply depends on this new dedicated Eclipse plugin. The java.lang.NoClassDefFoundError still rears its head.
Transition to Tycho 2.x.x since it supports the Directory location type. Unfortunately it is not possible to include the jar in the target definition because its packaging type is jar.

Maven: use dependencies from repository when running command line app?

I've used Maven to build my command line application. Now I'm going to distribute it as a jar file, and I need to handle the app's dependencies.
I don't want to include all dependencies in the jar file as described here.
The environment where my app will be run has Maven. I'd like Maven to run my jar looking at file META-INF/groupId/artifactId/pom.xml inside the package so it knows what the dependencies are and can find them in the repository.
Any ideas ?
Include a main class in the jar that 1) extracts the pom to a temporary file, and 2) launches a new maven process using this file with the -f parameter and the goals dependency:resolve and dependency:build-classpath
like this:
mvn -f /temp/tempfile.xml dependency:resolve dependency:build-classpath -DoutputFile=/temp/classpath.txt
then 3) reads the newly created classpath file and 4) launches a new java process using the new classpath file
java -cp yourjar.jar;<created classpath>
Your pom.xml will have to include all required repository information, of course
We can use, maven-jar-plugin instead, why because the classpath generated is not getting accommodated while copy paste with java command in command-line.
mvn -f /temp/tempfile.xml dependency:resolve dependency:build-classpath -DmdepoutputFile=/temp/classpath.txt
So wasn't able to succeed copying classpath.txt for the command,
java -cp yourjar.jar;<created classpath>
Mine is spring-boot application hence I have the following line with BOOT-INF/lib. For you it can be WEB-INF/lib in case of .war file or just lib/ in case of ant build based projects.
<classpathLayoutType>custom</classpathLayoutType>
<customClasspathLayout>BOOT-INF/lib/$${artifact.artifactId}-$${artifact.version}$${dashClassifier?}.$${artifact.extension}</customClasspathLayout>
BOOT-INF, comes up by spring-boot:repackage maven command and with the use of plugin,-spring-boot-maven-plugin that I have not Included here.
Please find maven-jar-plugin config here.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.pakage.SampleApplication</mainClass>
<!--<classpathPrefix>lib/</classpathPrefix>-->
<classpathLayoutType>custom</classpathLayoutType>
<customClasspathLayout>BOOT-INF/lib/$${artifact.artifactId}-$${artifact.version}$${dashClassifier?}.$${artifact.extension}</customClasspathLayout>
<!--<customClasspathLayout>BOOT-INF/lib/$${artifact.groupIdPath}/$${artifact.artifactId}-$${artifact.version}$${dashClassifier?}.$${artifact.extension}</customClasspathLayout>-->
</manifest>
</archive>
</configuration>
</plugin>

How to remove generated build artifacts from Maven's target directory?

How to remove generated build artifacts from Maven's target directory? Maven generates a jar or war file to target directory. I'd like to remove that file after maven has installed the jar/war file to local repository (that is, after maven has executed the 'install' goal). The remove could happen either at install goal or separate goal I execute manually.
Note, that I'd like leave other parts of target directory intact, for example target/site and target/surefire-reports.
Just use the clean plugin and run an execution after the install phase:
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>auto-clean</id>
<phase>install</phase>
<goals>
<goal>clean</goal>
</goals>
<configuration>
<filesets>
<fileset>
<directory>${project.build.outputDirectory}</directory>
<includes>
<include>**/*.jar</include>
</includes>
</fileset>
</filesets>
</configuration>
</execution>
</executions>
</plugin>
There is nothing built into Maven that can do this. You could use the antrun plugin to execute an Ant script after install that deletes the artifact, or use the exec plugin to use the command line to delete the artifact, or write your own plug-in.
I suggest there is little value, if any, in doing any of these things. Maven is designed to place intermediate and final artifacts in target to make follow-on builds more efficient. The reason that there is nothing available to do this already is an indicator that this is of little value. If it is of value to you, you have a few options.
I know I am a little bit late. But I guess the issue was, that a maven project archives the artifacts automatically. In my case, I disabled the automatic archiving and just archived the artifacts manually using the post build actions. This way, only the artifacts that I am interested in are archived. I am willing to leave the generated artifacts on disk until the next build runs.

Maven: Including jar not found in public repository

If I was to use a 3rd party library that was not in the maven public repository, what is the best way to include it as dependency for my project so that when someone else checks out my code it will still be able to build?
i.e.
My Application "A" depends on jar "B" which does not exist in the public repository. I, however, wish to add "B" as a dependency to "A" such that when a person on the other side of the world could check out the code and still be able to build "A"
You can install the project yourself.
Or you can use the system scope like the following:
<dependency>
<groupId>org.group.project</groupId>
<artifactId>Project</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${basedir}/lib/project-1.0.0.jar</systemPath>
</dependency>
systemPath requires the absolute path of the project. To make it easier, if the jar file is within the repository/project, you can use ${basedir} property, which is bound to the root of the project.
If you have a parent project with a module that is in this situation (requires a dependency not in a repository) you can setup your parent project to use the exec-maven-plugin plugin to auto-install your dependent file. For example, I had to do this with the authorize.net jar file since it is not publicly available.
Parent POM:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<inherited>false</inherited>
<executions>
<execution>
<id>install-anet</id>
<phase>validate</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>mvn</executable>
<arguments>
<argument>install:install-file</argument>
<argument>-Dfile=service/lib/anet-java-sdk-1.4.6.jar</argument>
<argument>-DgroupId=net.authorize</argument>
<argument>-DartifactId=anet-java-sdk</argument>
<argument>-Dversion=1.4.6</argument>
<argument>-Dpackaging=jar</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
In the above example, the location of the jar is in the lib folder of the "service" module.
By the time the service module enters the validate phase, the jar will be available in the local repository. Simply reference it in the way you set up the groupid, artifact, etc in the parent pom. For example:
<dependency>
<groupId>net.authorize</groupId>
<artifactId>anet-java-sdk</artifactId>
<version>1.4.6</version>
</dependency>
Using system scope may work but it is not recommended even in the Maven specification.
it is not portable.
from Maven book:
system- The system scope is similar to provided except that you
have to provide an
explicit path to the JAR on the local file system. This is intended to allow compilation
against native objects that may be part of the system libraries. The artifact is assumed
to always be available and is not looked up in a repository. If you declare the scope to
be system, you must also provide the systemPath element. Note that this scope is not
recommended (you should always try to reference dependencies in a public or custom Maven
repository).
The best approach is to install to your local repository or to your enterprise repository to be accessible to all your peers.
this is very easy if you are using a repository manager such as Nexus.
This solution worked for me;
1. Created a local-maven-repo in my project's root directory and copied all my jars in the
2. Executed the following command to generate the necessary pom files and metadata etc for each and every jar that I needed to use;
mvn deploy:deploy-file -DgroupId=<somegroupid> -DartifactId=<someartifact> -Dversion=1.0.0 -Durl=file:./local-maven-repo/ -DrepositoryId=local-maven-repo -DupdateReleaseInfo=true -Dfile=<path to jar file>
This generated a new jar file with a pom file inside the local-maven-repo and I was able to include into my project as a dependency like this;
<dependency>
<groupId>somegroupid</groupId>
<artifactId>someartifact</artifactId>
<version>1.0.0</version>
</dependency>
Then mvn package ensured that my project dependencies are resolved and packaged with my war file.
If you are using groovy/grail tool suite (GGTS) then you can directly import that third party dependency (but be sure you have that third party dependency in your local repository) using below steps :
Go to the Project Explorer and right click on project.
Click on import option.
Expend the maven option and select Install or deploy an
artifact to a maven repository and click next.
Brows and select that third party dependency using Artifact File
option and enter the detail of Group Id, Artifact Id and Version
using POM.xml file and click on finish
Wait some moment and possibly error would have gone for that problem.
Generally speaking, you should first put the 3rd party jar into your local repository. After that you can use it by adding the dependency into pom.xml.
For example.
1.put the jar into your local repository first:
mvn install:install-file -Dfile=<path-to-file>
Note: this command requires maven-install-plugin version 2.5 or later. If not, You can refer to Here
2.use the jar by adding the dependency into you project's pom.xml.
just add this into the pom.xml of your project:
<dependency>
<groupId>${the groupId in the jar's pom.xml}</groupId>
<artifactId>${the artifactId in the jar's pom.xml}</artifactId>
<version>${the version in the jar's pom.xml}</version>
</dependency>
3.you can then package or deploy your project by running mvn package or mvn deploy
The 3rd party jar will also be included in the package.

Trigger a maven install command from another maven install command

Is there a way to trigger a maven install command from another maven install command?
In other words, I would like to be able to execute a maven install command on a maven project (in eclipse) and I want that this will automatically cause an install command on another maven project.
Is that possible?
The Maven way to "trigger" another build is to define a multi-module build. A parent pom project can specify modules, that will all be built using the standard lifecycle. So running mvn install on the parent would mean that each module is built in turn.
The parent is defined with pom packagin, and would have a modules declaration like this:
<modules>
<module>module-a</module>
<module>module-b</module>
</modules>
Alternatively it is possible to attach additional artifacts to a build so they are deployed alongside the primary artifacts (assuming they've already been packaged, you can use the build-helper-maven-plugin to attach an arbitrary file to your pom, so it will be deployed with the specified classifier. The following configuration will attach the specified file as my-artifact-1.0-extra.jar
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>/path/to/extra/file.jar</file>
<type>jar</type><!--or specify your required extension-->
<classifier>extra</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
As pointed out, the maven way to launch a goal (lets say mvn install) on a set of modules is to organize them as a multi-module project and to launch the goal on the parent pom. Behind the scene, Maven will use a "Maven reactor" for this work. The reactor will calculate the build order by doing a topological sort of the nodes of the directed graph constructed by the dependency relation between modules. This graph is constructed by looking at <modules> and <dependencies> tags in poms.
But launching maven from a parent is not the only option and maven offers more possibilities to play with the reactor (e.g. making a project and its dependencies or those that depend on it):
With maven 2.0.x you have to use the reactor plugin : http://maven.apache.org/plugins/maven-reactor-plugin/ (see Reactor: My New Favourite Maven Plugin too)
With maven 2.1+ you can use native command line options : http://www.sonatype.com/people/2009/03/maven-210-released/ (see the new build mode options -amd, -rf, -am, -pl)
Check it out, it might help you to achieve your goal.