Intellij not recognising symbols in Maven POM - java

I'm working with a project that has, historically, been supported and developed in an Eclipse environment. I'm hoping to move this over to Intellij, and I'm currently using the full (Ultimate) package.
There are a few intricacies of the build process that don't appear to be working, which relate to selectively building the resources for the project. I could work around this, but would rather try and understand why IntelliJ and Eclipse are building the same project in a slightly different way.
I've noticed in my parent POM that the following code has an issue:
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.2</version>
<configuration>
<includes>
<include>**/*.js</include>
</includes>
<nosuffix>true</nosuffix>
</configuration>
</plugin>
Intellij is saying element includes is not allowed here' and itcannot resolve symbol 'include'`.
As far as I can see, the declarations are valid and in the correct place, and maven appears to be set up as required with the maven plugins installed as required too. The POM uses the http://maven.apache.org/maven-v4_0_0.xsd schema.
This kind of stuff has generally been left untouched for a number of years, but I can't see why it is having issues with this particular symbol/declaration?
As above, I've checked the plugins, Maven settings, all the usual suspects. Another of the plugins uses <excludes> with no errors, which makes it a bit more of a puzzle to me?
Can anyone help?

Related

Configure maven plugin version without changing pom.xml manually

Problem Description
I'm working with a collection of old projects from defects4j. My problem now is that since I want to combine those projects with a newer maven plugin, a regression test tool, there are some issue with the maven surefire plugin version.
In the pom.xml that come along with the projects, there are no specifications of surefire version:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>plain</id>
<configuration>
<includes>
<include>**/*Test.java</include>
</includes>
<runOrder>random</runOrder>
</configuration>
</execution>
</executions>
</plugin>
However, the regression tool (made into a maven plugin), require surefire version of 2.14 and above. So I get error like this:
[ERROR] Failed to execute goal edu.illinois:starts-maven-plugin:1.4-SNAPSHOT:select (default-cli) on project commons-lang: Unsupported Surefire version: 2.12.4. Use version 2.13 and above
Efforts Done
I checked several stackoverflow posts, and they talked about the effective pom. When I run mvn help:effective-pom, I can see that the version of surefire used is
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
Question
Since the project collection in defects4j does not specify surefire version in their pom.xml, is there a way to specify the surefire version used to 2.14 or above from command line? I want to prevent from manually editing the pom every time.
Update
by running mvn dependency:resolve-plugins, i get
Plugin Resolved: maven-surefire-plugin-2.12.4.jar
So it seems to me that somehow maven use 2.12.4 as a default. The reason maybe that I used this version previously. How do I fix this?
Without modifying the pom manually?
Any advice will be welcomed!
Update:
Problem solved by editing maven's super pom.
Maven takes the newest version from the repository if there was no version fixed in your POM, parent POM or the super POM (from which every Maven project inherits).
It is best practise to fix a version "manually" in the POM. The best place for this is a parent POM from which the projects inherit (this means, only one place to change).
You cannot just supply a version from command line. Unless you do some tricks like putting <version>${surefire.version}</version> into the plugin definition and set this property from command line.
I'm 4+ years removed from working with poms so don't remember everything, but consider a couple of things.
First, since the pom you show isn't specifying the version of surefire to use I don't think that the 2.12.4 version can be coming from that directly. Try getting a dependency tree to see where things are coming from. Try How can you display the Maven dependency tree for the *plugins* in your project? for that and a few other suggestions.
Second, I think I recall that in your own pom you should be able to specify the version of plugin to associate with a dependency that doesn't specify one. You'll have to research that option yourself.
I think your best bet is the dependency tree to find what's using what and where things are coming from. If you get the tree and still can't figure out what to do try adding the tree output to your question. (You can edit out parts that are proprietary, or clearly unrelated.)

Maven build failure involving MANIFEST.MF classpath in dependency JARs

First off, I'm a long time user (and beneficiary) of StackOverflow, but this is my first question. I've done plenty of searching on this topic, but most of the articles I've turned up talk about generating JAR files, not working with 3rd party JARs from the Maven Central repo which I don't really have the power to fix. The few solutions I've seen floating around aren't really acceptable.
The problem is that most of the jaxb JARs found in the Maven Central repository contain classpath entries (in the MANIFEST.MF file) that point to dependencies, and those dependencies are specified with relative paths -- typically assuming that dependency bar.jar exists in the same directory as foo.jar.
This is fine if you have all your JAR dependencies in a single lib directory, for example. But:
Maven wants to maintain its own local repository, so every single packaged JAR lives in its own directory (with each version in a separate subdirectory).
Maven JARs are typically named with the version info embedded in the filename, whereas the classpath entry in MANIFEST.MF specifies the dependency with just the base filename (no version).
The net result is an error message like this:
[ERROR] bad path element
"C:\Users\rpoole\.m2\repository\com\sun\xml\bind\jaxb-impl\2.2.11\jaxb-core.jar":
no such file or directory
One solution is to write a script or small app to go through all the JARs and strip out the classpath info from the embedded MANIFEST.MF file. But that is not very clean, and requires an extra step before doing the actual build.
Another potential solution is that some newer published versions of the JARs in question have supposedly fixed this classpath problem, so therefore use the latest and greatest. Unfortunately, this app I'm working on is legacy, and is being developed for a 3rd party, so I can't update the dependencies beyond a certain version. So far, all the jaxb JARs that I have poked into seem to have issues.
Is there a way to tell Maven to ignore the embedded classpath in the JAR and only rely on Maven's own dependency resolution? I've tried things like reordering dependencies, but that doesn't work (or moves the build problem from one subproject to another).
One additional annoyance: There is a "blessed" Maven repo we have that seems to let the build complete with no problem, but so far I've been unable to figure out why this particular set of JARs builds OK. I suspect someone may have gone in and tweaked some JARs or POMs manually, but there's scant information, and diff tools aren't really helping much.
Regardless, the project should build from scratch.
What would be nice is if I could specify something like an exclusion block in the pom.xml for the subproject that's breaking, but for dealing with a JAR's embedded classpath instead of Maven's own transitive dependencies (specified by groupId/artifactId).
Edit: Apparently, some people believe that this is impossible, and that Maven ignores the Class-Path entry in Manifest.MF. However, this is a known issue, as discussed in this StackOverflow article. There's also another good article which explains some of the history of this a bit better.
The problem is that I can't go through the JARs and edit the MANIFEST.MF files on each as part of the build process. That's just not a practical approach, even if automated by script. I need a solution that actually will work for code that is already in production. These issues were supposedly fixed in later versions of the JARs in question, but I may not be able to use newer versions of those.
Additionally, one of the proposed fixes is to add -Xlint:-path to the compiler args, which suppresses the error message. However, the build simply fails at another point for me, so at first blush this does not appear to be a good solution either. I'll be trying this again because according to this, the syntax for compiler arguments inside POM files is a bit wonky.
I hate answering my own question, but I finally did manage to get past this problem. For those who keep insisting that Maven builds can't possibly be affected by the Class-Path entry in a jar's MANIFEST.MF, please read this article by Michael Bayne. It summarizes the problem and the solution rather nicely. Hint: javac certainly does care about the embedded classpath in jars.
The trick is to add -Xlint:-path to the compiler arguments, although I was dubious of this solution initially. Doing this will suppress the bad path element warnings/errors, and therefore Maven won't prematurely halt the build. The problem I had was figuring out the correct syntax for embedding these arguments in the pom.xml. That's where this article comes in handy. Therefore, the compiler plugin's configuration has to look like this to be understood properly:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java-version}</source>
<target>${java-version}</target>
<compilerArguments>
<Xlint/>
<Xlint:-path/>
</compilerArguments>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
</plugins>
Note that this syntax is not very good XML (as Bayne points out), and most IDEs will flag the second Xlint line as an error, but it will work with Maven. Using the syntax given in some Maven tutorials may result in the arguments not being passed to the compiler at all, or only the last argument being passed.
Once this problem is taken care of, you may discover other build problems (I certainly did), but at least those problems won't be hidden from you any longer.
The problem is that you are referencing a post which is seven years old..and don't use more recent versions of the maven-compiler-plugin:
The arguments to the javac compiler can better done like this:
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<compilerArgs>
<arg>-Xlint</arg>
<arg>-Xlint:-path</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
[...]
</build>
[...]
</project>

PMD multiple rulesets pass build but single ruleset fails build

I am using PMD maven plugin for my project and I am seeing very strange behavior in it. The following pom.xml configuration fails the build with violations in basic.xml -
<configuration>
<rulesets>
<ruleset>${project.basedir}\ruleset\basic.xml</ruleset>
<!-- ruleset>${project.basedir}\ruleset\braces.xml</ruleset>
<ruleset>${project.basedir}\ruleset\design.xml</ruleset>
<ruleset>${project.basedir}\ruleset\controversial.xml</ruleset>
<ruleset>${project.basedir}\ruleset\coupling.xml</ruleset>
<ruleset>${project.basedir}\ruleset\clone.xml</ruleset>
<ruleset>${project.basedir}\ruleset\comments.xml</ruleset-->
</rulesets>
</configuration>
But the below one passes the build smoothly -
<configuration>
<rulesets>
<ruleset>${project.basedir}\ruleset\basic.xml</ruleset>
<ruleset>${project.basedir}\ruleset\braces.xml</ruleset>
<ruleset>${project.basedir}\ruleset\design.xml</ruleset>
<ruleset>${project.basedir}\ruleset\controversial.xml</ruleset>
<ruleset>${project.basedir}\ruleset\coupling.xml</ruleset>
<ruleset>${project.basedir}\ruleset\clone.xml</ruleset>
<ruleset>${project.basedir}\ruleset\comments.xml</ruleset>
</rulesets>
</configuration>
The build should have failed in the second scenario also. As per what I have noticed, if the last rule (in above example comments.xml) does not have any code violation then the build will not break even if any of the rulesets above it (basic.xml, braces.xml, etc.) have code violations. I am unable to understand the reason behind this behavior. Can someone help me out with this?
I found the issue. There was an issue with Maven Plugin version 3.3 . Now I am using version 3.1 and the exact same code is working as expected.

How to configure custom maven project structure

I know that typically maven structure is like this:
pom.xml
src
- main
- web
- WEB-INF
However, I have a project which has the following structure
src
- main
web
- WEB-INF
The latter of the two above currently does not use maven. I've started using maven for this project locally by making the structure conform to the maven standard. However, I now want to automatically build this project from jenkins by getting it out of the source control (svn). So I would like to just add a pom.xml which is aware of the fact that web isn't inside src
Is this possible to do with maven?
You can configure the maven-war-plugin to use another warSourceDirectory but as Jeff Storey explains in his answer it is really not recommended.
This is how you would do it:
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<warSourceDirectory>web</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
One of several problems is for example that the maven-jetty-plugin will not run out-of-the-box. It will by default look in src/main/webapp so that has to be configured.
You might not use the maven-jetty-plugin but you get the idea.
Using the maven war plugin properties, you can set the warSourceDirectory property http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html (I'm not sure exactly what problems you're having, so this may or may not solve your specific problem).
However, maven is very opinionated and I would strongly recommend using the expected maven structure. Other plugins may give you unexpected problems down the road, and maven life is generally a lot easier when you follow their conventions.

Moving to Maven from GNUMake

I've been a long time user of the Make build system, but I have decided to begin learning the Maven build system. While I've read through most of the online docs, none seem to give me the analogies I'm looking for. I understand the system's lifecycle, but I have not see one reference to compile step dependencies. For example, I want to generate a JFlex grammar as part of the compile lifecycle step. Currently, I see no way of making that step a pre-compile phase step. Documentation seems to be limited on this. In general, the concept of step dependencies seem to be baked into Maven and require a plugin for any alteration. Is this the case? What am I missing, because currently the Maven build system seems very limited in how you can setup compilation steps.
You can do anything in Maven. It generally has a default way to do each thing, and then you can hook in and override if you want to do something special. Sometimes it takes a lot of Stack Overflowing and head scratching to figure it out.
There is even an official JFlex Maven plugin.
Whenever possible, find someone who has made a Maven plugin do what you want. Even if it isn't 100% right, it may at least give you an idea on how to make maven do something.
Minimal configuration
This configuration generates java code of a parser for all grammar files (.jflex , *.jlex , *.lex , .flex ) found in src/main/jflex/ and its sub-directories. The name and package of the generated Java source code are the ones defined in the grammar. The generated Java source code is placed in target/generated-source/jflex , in sub-directories following the Java convention on package names.
pom.xml
<project>
<!-- ... -->
<build>
<plugins>
<plugin>
<groupId>de.jflex</groupId>
<artifactId>jflex-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<!-- ... -->
</build>
<!-- ... -->
</project>
This feels like the maven way to do things. Put your stuff in the right folders (src/main/flex), and this plugin will automatically build it into your project. If you want to do fancier custom stuff, there are some options. but Maven is all about favoring convention over configuration.
To be frank I think that your current mindset maps much better to ant than to maven, and I would suggest starting with that.

Categories