maven with eclipse error "Path must include project and resource name" - java

I've recently started using maven with eclipse.
I've set up several projects and I've noticed that if I try and specify a build directory (to over-ride target) which is outside the project directory, I get an error when doing "update project":
'Updating Maven Project' has encountered a problem.
An internal error occurred during: "Updating MAven Project".
Path must include project and resource name: /[my project name]
I need to build outside the project. How can I get around this? Can I perhaps have maven automatically create a softlink?

Although this is a fairly old thread, I recently encountered this problem and was able to solve it. The reason why maven threw this error is I had, somewhere in my pom.xml file, an absolute path that was not consistent with the directory from which the project was imported into eclipse. So I had two absolute paths (one incorrect, or points to a previous location) that point to resources, i.e. project.build.outputDirectory, in the pom.xml file.
The Solution: Locate the faulty absolute path, /home/userA/ProjectB/bin, and replace with a relative, ./bin, path. Update the project in eclipse and you should be fine.

This is a bit old thread, but since nobody gave a correct answer...
The following Eclipse error:
An internal error occurred during: "Updating Maven Project".
java.lang.IllegalArgumentException: Path must include project and resource name:
at org.eclipse.core.runtime.Assert.isLegal(Assert.java:63)
at org.eclipse.core.internal.resources.Workspace.newResource(Workspace.java:2069)
at ...
can occur in many different scenarios - in the Eclipse Bugzilla you can find a lot of similar bug reports.
In situation you described, it is a known limitation. But it's not a m2e fault - simply Eclipse JDT does not allow setting output dir outside of the project.
IMHO it's a pity, because if maven supports a such layout, so I would expect that m2e should as well.
I've reported it as a bug 493229. But it has been closed with status WONTFIX.

To answer the last paragraph in your question, you can get around the problem with a softlink. I did it a little differently than what you guessed at. It's not Maven that creates the symlink because this is a problem with Eclipse JDT (as others have pointed out) which runs without invoking Maven at times (it seems). Here's what I did, with all paths relative to my Maven project directory:
1) I wanted my actual build directory to be "../../local/java/scratch/target"
2) I created a softlink: ln -s ../../local ./
3) I added this entry to my "pom.xml":
<build>
<directory>${project.basedir}/local/java/scratch/target</directory>
</build>
Now Eclipse JDT happily thinks it's building within the project directory but in reality the path "../../" takes it outside of the project directory. My guess is that an absolute path would have worked too.

For example, if you'd like to have build contents in some folder outside workspace, you can have something like :
<build>
<plugins>
<plugin>
<executions>
<execution>
<phase>move-build</phase>
////do your build
</plugin>
<plugin>
<executions>
<execution>
<id>copy-resources</id>
<phase>move-build</phase>
// do your copying to external
</plugin>
<plugin>
<executions>
<execution>
<phase>move-build</phase>
// do your deletions from target
</plugin>
</plugins>
</build>
then you can call mvn move-build to have your build, copy, delete done.
here is an example of copy to external folder and delete, you can combine both into your move-build phase as described above

why can't I build somewhere like ../build
Yes you can build in some folder called build provided it contains the pom.xml.
The pom.xml file is the core of a project's configuration in Maven. It is a single configuration file that contains the majority of information required to build a project.
In short the pom.xml will have all information to build your project.
pom.xml is a file which contains the project configuration details used by Maven. It provides all the configuration required for a project.

I was convinced that this problem was caused by either Maven or Eclipse, perhaps because I found this and other references to that combination on Stackoverflow.
After considerable investigation, and going slightly mad, it turns out that Git was involved - though I don't know if it was the cause.
My Maven project consists of several "nested" POMs, and I don't open the parent POM in Eclipse, but only the children. I had a couple of files (batch scripts) at the top level which I hadn't committed to Git, but once I committed these the
Path must include project and resource name
problem disappeared completely.
Eclipse version: 2020-12 (4.18.0)

Related

Why is m2e putting the wrong version of some artifacts into the .classpath file?

I am currently using Eclipse 2021-12 on Windows. I work almost exclusively on Java (1.8) Maven projects that are stored in Git.
I noticed that a project that I just started looking at (cloned it from our central repo) was getting a weird runtime error that didn't make sense. The error made it seem like it was referencing an older version of one artifact. I checked the maven dependencies both from the "Dependency Hierarchy" view and from the command line with "mvn dependency:tree". Both confirmed that I had the correct version of the artifact.
However, the .classpath file, along with the "Libraries" tab in "Java Build Path" had the previous version of the same artifact.
I tried "Update Project" with "Force Update of Snapshots/Releases" checked. No change.
I then went down the rabbit hole, deleting the project, then the Eclipse dot files, and then reimported the project from the git repo. That made it even worse. It didn't even acknowledge it was a Java project. I couldn't figure out how to fix this (outside of simply manually editing the .project file, which will be a last resort), so I enabled "Faceted Form", and that came out with Java automatically selected. Then I noticed it didn't even think it was a Maven project, even though it had selected the proper source directories. I selected making it a Maven project. And finally, that just got me back to where I started, with the wrong version of the artifact specified in the .classpath file.
Finally, I made a copy of the .classpath file and simply manually edited it. I found several artifacts with the same problem. And by "same", I mean several artifacts all developed internally, which should have been at version "2.6.0", which is what is specified in the pom hierarchy, were set to version "2.5.0".
I then ran the service, and it ran fine.
I have no idea whether there are any other discrepancies, being differences between the Maven-specified version and the version in the .classpath file. That would require more thorough examination. I used to think that situation would have been impossible.
Update:
From the comments, I decided to step through this again more carefully, noting the results at each step.
I first deleted the existing Eclipse project, without deleting the project contents on disk. I then copied and removed the .classpath, .project, and .settings. I then imported the project from the Git repo. It auto-detected "Maven" for "Import as". I had "Detect and configured project natures" checked.
This resulted in a Maven project, but not a Java project, so it didn't even generate a .classpath file. The .project file only had the "maven2Nature" and associated builder. This somewhat explains why the Maven import didn't generate the correct .classpath entries.
At this point, the only way I know to make it figure out it is a Java project, outside of manually editing the .project file, is to convert to Faceted form. This successfully added the "javanature" and associated builder, and detected src/main/java and src/test/java, but I still don't have any dependencies.
At this point, I tried "Update Project" with "Force" checked. That did nothing. I tried "Disable workspace resolution" (which I want anyway). That did nothing.
It's possible that my most recent attempt got an almost sane .classpath file by using "mvn eclipse:eclipse". I know, it's supposed to be a bad idea, but sometimes it seems like the only thing that works.
It appears that the key here is that the Maven import from Git doesn't first detect it's a Java project.
Just in case, I did it all again, doing a top-level "File->Import->Existing Maven Project", with almost exactly the same result. The import from git created the project name as the git repository name, and the import from Existing created the project name as the project name from the pom.xml, the two of which are only different by case. Otherwise, the result was identical.
I then tried again, with no dot files, and I copied in an almost empty .project file, removing all but the java nature and builder. I tried doing git import, but that didn't auto-detect Maven, so I went back to Import Existing Maven Project, but that resulted in a brain-damaged Java project. I'm guessing the way I did it made it so that it didn't know what Java compiler to use, so it couldn't find "java.lang.Object".
I then started over again, removed the dot files, imported from git (auto-detects Maven), then converted to Faceted form, which auto-added Java nature, then ran "mvn eclipse:eclipse" from the command line. This brought me back to an almost correct configuration, with several artifacts with the almost correct version, with all references using M2_REPO.
This makes it clear it wasn't m2e that was producing the incorrect version numbers, but the "eclipse" plugin. M2e didn't even produce a .classpath file, because it didn't know it was a Java project.
Update:
I believe I've found the element in the original pom.xml such that when this project is imported, m2e doesn't acknowledge it is a Java project, which results in no .classpath file being created.
Before I post what I found, I wanted to say that I didn't write this, I'm just trying to figure out why it's broken. The thing that someone put in here is something I would never do, and I had noticed it earlier, but it didn't occur to me it would result in what I've been seeing.
What I found in plugins was a "lifecycle-mapping" plugin, looking like this:
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<versionRange>[3.8.0,)</versionRange>
<goals>
<goal>testCompile</goal>
<goal>compile</goal>
</goals>
</pluginExecutionFilter>
<action> <ignore></ignore> </action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
When I change nothing else in the pom.xml but comment this out, importing this project works correctly.
Frankly, I don't really know why some people in my org do this. I think they must give up trying to properly configure m2e, and this is just a way to get rid of the red Xs (even if it doesn't actually fix anything).
Obviously, the fix is to just remove this, but I'd appreciate any background anyone could provide on why someone might do this, and what they should be doing instead.

Missing class files after Maven build

I'm using Maven 3.3.9 on Windows 10. I have a multi-POM project, and I want to share some test resources across the Maven projects. As we all know the files in src/test/* won't be included in distribution JARs, so I created a separate project just for the test resources (and accompanying Java class with the resource names), so that I could share this project across other projects.
For the sake of illustration let's say that there are two files in the foo-test project:
src/main/java/com/example/foo/test/FooTestResources.java
src/main/resources/com/example/foo/test/resource.txt
Straightforward, right? Except that when I build the project in Maven, the resulting JAR file only contains com/example/foo/test/resource.txt! The class file, which I would expect to be in com/example/foo/test/FooTestResources.class, is missing.
In fact they this file isn't even in the target directory, so it's as if Maven isn't even compiling the source file. I searched my project directory for FooTestResources.class, and it doesn't exist. Only the source code file FooTestResources.java is there.
When I build the project on Eclipse 4.6.3, Eclipse generates the file target/com/example/foo/test/FooTestResources.class as expected. When I do a mvn clean install it disappears.
What is going on?
I found it! Here's the story.
Once upon a time I had a project that needed two JARs. One JAR would contain the source code along with most of the resources, and the other would contain just a single resource. Rather than creating two projects (and two Git repositories), I tried to be lazy and I created two POMs. One POM built everything normally except for the one resource, the other… (you guessed it) ignored all the source files and generated the POM files.
You can read the full technical details here: https://globalmentor.atlassian.net/browse/CLOGR-3
For various reasons that didn't turn out to be the most manageable approach, so I split out the two POMs into separate projects repositories, as they should have been to begin with.
Unfortunately, somewhere along the way I copied the crucial lines from one of those POMs into this POM.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<skipMain>true</skipMain>
<skip>true</skip>
</configuration>
</plugin>
The skipMain is what does it. Bye-bye source files. (Apparently Eclipse ignores the details of this section.)
I was also skipping tests as well; I basically had just copied from the wrong POM, a POM I don't even have around anymore.

GAE ClassFormatError: Incompatible magic value 4022320623 EFBFBDEF

I have a simple webapp in an mavenized Eclipse project.
My pom.xml contains some lines that add Google's appengine-maven-plugin to the build plugins.
When I run mvn appengine:devserver I eventually get an error telling me that my class could not be loaded:
[INFO] WARNING: Error starting handlers
[INFO] java.lang.ClassFormatError: Incompatible magic value 4022320623 in class file com/teamlazerbeez/http/di/StartupListener
That number is EFBFBDEF in hexadecimal notation, something that is clearly not CAFEBABE, the byte sequence Java class files should start with.
I only found this and this on the subject matter, which leads me to believe that the encoding went wrong during either writing or reading the class file.
Is this the problem? How do I force maven to read/write classes with e.g. UTF-8 encoding?
And what is a good encoding?
My java files are all encoded the same way: Eclipse says ISO-8859-1, Notepad++ says ANSI.
PS: I'm on a windows machine.
As Joakim Erdfeld's answer suggests, one of the plugins is fiddling with the build.
The culprit is the maven-war-plugin v2.3, but only in the following situation:
Having the GAE nature enabled on the mavenized Ecipse project (where the appengine-maven-plugin v1.7.5 is listed in the pom.xml) will break running mvn appengine:devserver iff the following conditions apply:
'default output folder' (in the Eclipse project's 'Build Path' settings) is set to src/main/webapp/WEB-INF/classes/ (required for the GAE Eclipse plugin to work)
The GAE plugin decided to put GAE-jars in src/main/webapp/WEB-INF/lib/, even though these jars are already in the classpath.
In conclusion, the maven-war-plugin improperly copies .class and .jar files from your WEB-INF/ to your resulting .war file. Somewhere in the process, it mis-encodes these files.
Check your src/main/webapp/WEB-INF folder, it should not contain a classes folder.
If it does, it means you probably misconfigured your eclipse project.
One case we encountered is that the developer imports a maven project and runs the project "as a web application". The first time he does this, Eclipse asks him where the webapp folder is. If you answer src/main/webapp then Eclipse will put its classes there, and it will get messed up by maven after.
To solve this, delete the project from Eclipse and remove the src/main/webapp/WEB-INF/classes folder, then re-import the project.
And when Eclipse asks where the webapp folder is, it is in target/yourproject-yourversion.
Something in your maven build is messing with the class files after the compile and before the package phases.
Start by commenting out all of your <plugins> and then adding them back 1 at a time till the build breaks again.
Be sure you run > mvn help:effective-pom to check on what your pom looks like when it has been fully resolved to parent poms and whatnot.
(Experimental) You can possibly even get the build itself to tell you if the classes are bad by simply using the project-info-reports command line for the dependencies report.
> mvn clean org.apache.maven.plugins:maven-project-info-reports-plugin:2.6:dependencies
I found this question which also mentioned the invalid magic number EFBFBDEF. It also seems to suggest that you set the maven encodings properly. Use the following property:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
But I think that this only helps if you get an encoding warning during the maven build process.

dependency not found at runtime maven

I'm new to maven and somewhat new to java. Tried google and related sources, but I didn't find one which resembled my situation.
Right now, I have maven project X and Y. X can be seen as a shared library with some utilities, Y is a simple JFrame with a "hello world" printed and a call to a static method in X.
I do a "run as maven install" on project X, I get a "build successful". I add project X as dependency in project Y (using the pom-editor in Eclipse, browsing the repository and locating it). I do a "run as maven package" on project Y, I get a "build successful". Upon running project Y either via java -jar or inspect the produced jar, project X is missing everywhere and I get a fancy class not found exception. Eclipse finds it and there are no compile errors in the source editor.
Why is it only working in the Eclipse editor and not as jar?
POM:
<dependency>
<groupId>com.company.deployment.shared</groupId>
<artifactId>com.company.deployment.shared</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
Maven doesn't produce a combined JAR file for you. What Eclipse is doing is looking at the Maven configuration and adding all the required classes / jars to your classpath for you when it runs.
If you want to run your program from the command-line, you will need to add all the JARs manually to your classpath.
Alternatively, you could run your program directly from Maven which should set up all your dependencies. There are a number of options depending on what you want to do, i.e. if it's an application which is meant to be run by an end-user you could look into the one-jar Maven plugin.
I recommend that you take a look at the Maven shade plugin. This produces an "uber-jar" comprising your project and all of its dependencies. It can also do other things such as setting the entry point class to make your JAR file an executable JAR.
You may also find exec-maven-plugin helpful
mvn exec:java -Dexec.mainClass="com.example.Main" [-Dexec.args="argument1"] ...
mvn exec:exec -Dexec.executable="maven" [-Dexec.workingdir="/tmp"] -Dexec.args="-X myproject:dist"
If your client can not download dependencies from maven m2 repo on the fly like behind firewall or no internet connection, then you also need to package the dependencies using maven-dependency-plugin to copy all dependencies and maven-assembly-plugin to assemble dependencies
It doesn't work because Maven resolves dependencies when building your project, but doesn't put all the dependencies magically in your jar. You're supposed to run your app with all its dependencies in the classpath:
java -classpath X.jar;Y.jar com.foo.bar.Main
Or you have to customize the maven jar plugin in order to create an executable jar, as described here. And you may also use the maven assemby plugin to copy all your Y project's dependencies to the target directory, next to the generated Y.jar.
The artifact produced in project Y contains only build results in project Y only, not including its dependencies.
If you want to build a JAR in Y, which u can execute directly, you can consider using assembly plugin.
For example, the easiest way to build a uber-jar for project Y:
<project>
...
<build>
...
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-all-in-one-jar</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
...
</project>
Apart from a normal artifact, an assembly which contains classes etc from dependencies will be created, which is suitable to be executed by java -jar
visit http://maven.apache.org/plugins/maven-assembly-plugin/ for more sophisticated usage.
Phil Sacre already explained the basic problem well (there basically is just no information on where to find the X.jar embedded in your Y.jar).
Additionally you can also look at the appassembler-maven-plugin (which can e.g. generate launch scripts for your Y project that already have the right classpath set) and/or the exec-maven-plugin (which you can use to e.g. directly launch Y with the right classpath using maven).

How to reference javadocs to dependencies in Maven's eclipse plugin when javadoc not attached to dependency

I use Eclipse, Maven, and Java in my development. I use Maven to download dependencies (jar files and javadoc when available) and Maven's eclipse plug-in to generate the .project and .classpath files for Eclipse. When the dependency downloaded does not have attached javadoc I manually add a link for the javadoc in the .classpath file so that I can see the javadoc for the dependency in Eclipse. Then when I run Maven's eclipse plugin to regenerate the .classpath file it of course wipes out that change.
Is there a way to configure Maven's eclipse plug-in to automatically add classpath attributes for javadoc when running Maven's eclipse plug-in?
I'm only interested in answers where the javadoc and/or sources are not provided for the dependency in the maven repository, which is the case most often for me. Using downloadSources and/or downloadJavadocs properties won't help this problem.
From the Maven Eclipse Plugin FAQ
The following example shows how to do
this in the command-line:
mvn eclipse:eclipse -DdownloadSources=true -DdownloadJavadocs=true
or in your pom.xml:
<project>
[...]
<build>
[...]
<plugins>
[...]
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<configuration>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
[...]
</plugins>
[...]
</build>
[...]
</project>
I'm running STS 2.8.1 which is basically eclipse + spring tools; In an existing maven project, I right clicked on the project -> maven -> Download Sources and Download JavaDocs
As mentioned in How to download sources and javadoc artifacts with Maven Eclipse plugin from other repository?, you can do this:
In Eclipse go to Windows-> Preferences-> Maven. Check the box that says "Download Artifact Javadoc." That has worked well for me.
You might consider just avoiding this problem completely by installing the javadoc jar into your local repository manually using the install-file goal and passing in the -Dclassifier=javadoc option. Once you do that the .classpath that mvn generates should be correct.
If you use a remote repo as a proxy to central you could also deploy the javadocs to that repo and then everyone else who uses that proxy will now get the javadocs automatically as well.
Generally Javadocs are not primarily used as dependency . Because these are neither required at compile nor runtime. It’s just to help the developer while developing or debugging.
Assuming using the java IDE Eclipse we can use the java docs as referenced. Following are the approaches we can associate the javadocs/sources with the respective jars.
1. If it’s non-maven project :
Download the javadocs jar or zipped file, whatever available and placed it in some directory.
Right click on the application project in the IDE Eclipse, click Properties and choose Java Build Path then select tab Libraries under the Java Build Path. Now expand the jar you want to link with java docs/source. Select the Javadoc location link and click on Edit button, a new window appears where we need to choose the javadocs jar path. Click OK and we have linked the javadoc/source with the respective jars.
2. If it’s a maven project
If we are using the Maven project then go to jar files under the Maven dependency under the project in Project Explorer view as shown below. Now right click on the jar file you want to add the Javadoc/source,  choose Maven then click on Javadoc or Source you want to link with the project. Now IDE will automatically download the required javadoc/source and will link it with the respective jar in the project.
You can verify this by right click on the project in the IDE and click on Java Build Path and select the Libraries tab under the Java Build Path and then expand the desired jar, here when you click the Edit button you will see the linked path of the Javadoc/Source with the respective jar as shown below in the image.
3. If it’s Maven project and we are setting the default behavior:
Eclipse will aquatically download the javadoc/source along with the main required jar at the starting.
By default setting instruction to Maven to download the Javadoc/sources for all the jars linked in the project.
Click Windows – preferences – select Maven and click the checkbox Download Artifact Javadoc as shown below
Now click on apply and save it and now when you create new Maven project , by default the Javadocs will get downloaded and linked with all the dependent jars in the project.
You can verify by right click on the project and Properties and under Java Build path can see the javadocs are linked with all the jars as shown below.
If your project is Maven project then It’s always best to use 2nd approach because by using this approach the IDE and Maven, takes care of downloading the correct version of the Javadoc/source and linked it with the relative jar as well.
Approach 3rd is bit costly because the javadoc/sources will be downloaded for-all the dependent jars, may be you are not interested for javadocs/sources for all the dependent jars.
Would having the sources for the dependency help? You can tell the eclipse plugin to download those (and refer to them in the .classpath) with -DdownloadSources=true

Categories

Resources