Gradle integration for eclipse keeps on changing .classpath file - java

My current configuration includes a Java WAR project using gradle with the java and eclipse-wtp plugins, and the latest version of Buildship for Eclipse integration (1.0.3 till this morning and 1.0.4 right now) along with Eclipse Luna.
After following this solution https://stackoverflow.com/a/9820317/1544713 (successfully) to avoid deploying the test classes to my local server, I noticed that every time I refreshed the project or closed and opened Eclipse, the .classpath file and .settings/org.eclipse.wst.common.component were changed to their previous state, which is something I that gives me problems (deploying the test classes to the local server implies that they will fail to be loaded due to the lack of some test time dependencies, and of course an undesired behaviour).
The content of .classpath is changed from (the right one):
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="FROM_GRADLE_MODEL" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="FROM_GRADLE_MODEL" value="true"/>
</attributes>
</classpathentry>
to this undesired state:
<classpathentry kind="src" path="src/test/java">
<attributes>
<attribute name="FROM_GRADLE_MODEL" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src/test/resources">
<attributes>
<attribute name="FROM_GRADLE_MODEL" value="true"/>
</attributes>
</classpathentry>
And in the case of .settings/org.eclipse.wst.common.component, these two lines are added (which again, I don't want them to be present):
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/resources"/>
I can't figure out if it is Gradle that is changing the files or Buildship, or even Eclipse. In any case, I guess there is a way to stop this happening. I have tried many alternatives, like the following configs in build.gradle:
eclipse.classpath.file.whenMerged { cp ->
cp.entries.findAll { it.kind = "src" && it.path.startsWith("src/test/") }*.output = "target/test-classes"
}
eclipse {
wtp.component {
file.withXml { xml ->
def node = xml.asNode()
def wbrNodes = node.'**'.findAll { it.name() == 'wb-resource' && it.'#source-path'.startsWith("/src/test/")}
if (wbrNodes.size() > 0) {
wbrNodes.each { n -> n.parent().remove(n) }
}
}
}
}
But this configuration works erratically (sometimes it seems to work, some other times it doesn't, and actually the first piece of code that starts with eclipse.classpath.file.whenMerged never works).
Thanks in advance.

After some time spent looking for possible solutions, and the cause of the problem, I've found out that the real problem was in fact Buildship, which was not paying any attention the the directives to the eclipse-wtp plugin in build.gradle, and instead it was taking its own approach to generate a .classpath and the related eclipse configuration files. At the same time, and so far (Buildship 1.0.5 released just today) there is no way to configure or manipulate Buildship while it is building its own model (when importing a Gradle project, when opening Eclipse or when refreshing a project e.g. with F5). As Lance_Java said in the Gradle forums (https://discuss.gradle.org/t/gradle-integration-for-eclipse-keeps-on-changing-classpath-file/11813/7?u=fbudassi), it's useless to use the eclipse-wtp plugin together with Buildship, since both take their own approach to generate the Eclipse configuration files.
So, the solution so far has been to remove Buildship from my Eclipse installation and instead replace it with the Gradle IDE Pack 3.6.x+0.17 plugin right from the Eclipse marketplace, which uses the build.gradle directives to build its own model, avoiding this way any possible conflict.
If anybody from Buildship gets to read this post, please, give us some hooks to the generation of the files. Again, as Lance_Java suggested, something like this would really help:
apply plugin: 'buildship'
buildship.wtp.component.file.withXml { ... }

Related

Eclipse IDE for Java Developers 2021-06 Cannot find class paths for jars

I have built a new machine and installed a fresh version of eclipse (Eclipse IDE for Java Developers 2021-06). If I run an old project it works. If I make a new project I the following error.
Exception in thread "main" java.lang.NoClassDefFoundError: net/crl/CRLibs/DBI
at EnvList.(EnvList.java:143)
Caused by: java.lang.ClassNotFoundException: net.crl.CRLibs.DBI
There are no errors in the code.
The build path looks like:
Line:143 is: static DBI db = new DBI();
DBI is defined in the crlibs jar.
In my old Eclipse (Oxygen) the build path looks like:
I tried adding the crlibs jar to the Classpath, but it will not let me save it (all boxes grayed out).
Now this code is copy of a template I use. The original runs just fine and its build path looks like the one from Oxygen.
If I comment out this line it will give the same error at the next library access.
It appears that the Class paths to the library are not being included.
Note The library was built with Oxygen. Do I need to rebuild it with the new version and if so will it then still work for all the code build with Oxygen.
How do I fix this?
Note:
Eclipse Java EE IDE for Web Developers.
Version: Oxygen.3a Release (4.7.3a)
Build id: 20180405-1200
And
Eclipse IDE for Java Developers (includes Incubating components)
Version: 2021-06 (4.20.0)
Build id: 20210612-2011
EDIT:
Here is the .classpath file.:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-16">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="E:/Documents and Settings/Cliff/libs/crlibs.jar" sourcepath="E:/Documents and Settings/Cliff/Libs_src/CRLibs/src/net/crl/CRLibs">
<attributes>
<attribute name="javadoc_location" value="file:/E:/Documents%20and%20Settings/Cliff/Libs_src/CRLibs/CRLibs/doc/"/>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="bin"/>
</classpath>
The path to the jar is there?
EDIT2
The command line:
In the figure below
You must delete the jar from Modulepath THEN add it to the Classpath. The JRE seems just fine in the Modulepath. Once my library is in the classpath the code works.

Iterate through maven project's dependency jars with eclipse-resource-api (plugin development)

I have a maven project. And i want to iterate through its dependency jar projects and read some property files in them.
With eclipse resource api, i can get an IProject instance in workspace and access its classpath file.
Class-path has the following structure.
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
How can i extract the actual dependency jar locations from this?
i was expecting something like this instead
<classpath>
<classpathentry kind="var" path="M2_REPO/apache-xerces/xercesImpl/2.9.1/xercesImpl-2.9.1.jar"/>
<classpathentry kind="var" path="M2_REPO/apache-xerces/xml-apis/2.9.1/xml-apis-2.9.1.jar"/>
</classpath>
2.Or is there any better approach than this to read through maven dependency jars programatically?
The getResolvedClasspath method of IJavaProject deals with resolving containers:
IProject project = ... get project
IJavaProject javaProject = JavaCore.create(project);
IClasspathEntry[] classPathEntries = javaProject.getResolvedClasspath(true);
The JavaDoc says:
This is a helper method returning the resolved classpath for the
project as a list of simple (non-variable, non-container) classpath
entries. All classpath variable and classpath container entries in the
project's raw classpath will be replaced by the simple classpath
entries they resolve to.

Why can't I add a "Groovy Nature" to a java project?

I have some java projects that have been around for a long time and am currently using a pretty recent version of SpringSource Toolsuite and the groovy plugin which works fine (this was added for people who don't read beyond the first paragraph).
I can create a Groovy project or I can convert a Java project to a groovy project, but I'd really like to add a Groovy nature to my java project (I don't think the team would be very happy about me converting all the projects over to groovy projects!)
The problem is that the "Groovy" menu item containing "Add Groovy Nature" doesn't appear in any java projects (legacy projects or new ones I create). It appears in a Groovy project with "Remove Groovy Nature", but not in java projects.
Everything else works pretty well.
Oh also, not using maven, just straight eclipse & ant--I can deal with the Ant part it's just the eclipse integration that's being probleematic.
Am I missing a setting or something?
My colleague and I had the same problem today. We manually fixed it using basically this process:
Clean all projects without starting a new build.
Exit eclipse.
Add/edit the project configuration files below.
Start eclipse.
Refresh project.
Enable Project->Build Automatically.
Here are the files to add/edit:
.project : Add this line to the <natures> element:
<nature>org.eclipse.jdt.groovy.core.groovyNature</nature>
.classpath : Add this line:
<classpathentry exported="true" kind="con" path="GROOVY_SUPPORT"/>
.settings/org.eclipse.jdt.groovy.core.prefs : New file:
eclipse.preferences.version=1
groovy.compiler.level=-1
Note that the target project was already a java project. To add this stuff to a plain or other non-java project, you might also need to add the following:
.project :
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
.classpath : Copy from one of your java projects and edit appropriately. Here's a default .classpath file:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="bin"/>
</classpath>
Install Groovy eclipse plugin
http://groovy.codehaus.org/Eclipse+Plugin

Is there any way to prevent m2e from modifying the eclipse .classpath file?

I'm converting some of our projects into Maven projects, but m2e changes my .classpath JRE entry from:
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
to:
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
This causes a few errors like:
Description Resource Path Location Type Access restriction: The type
WindowsPopupMenuSeparatorUI is not accessible due to restriction on
required library C:\Program
Files\Java\jdk1.6.0_20\jre\lib\rt.jar DottedJPopupMenuSeparator.java /acommons/src/com/ks/acommons/gui/lookandfeel line
10 Java Problem
Is there any way I can make m2e not generate the .classpath file, or force it to use the workspace default JDK?
In my opinion, Maven is helping you here. It forces Eclipse to use a strict Java 1.6 environment and prevents you from using libraries which are not part of the standard distribution.
Typically this error message is hinting that you should be declaring a new Maven dependency, rather than relying on a JAR file being present in (e.g.) JRE/lib/ext.
This is currently not possible, but it may be if m2e bug 405661 is fixed.
As of today (m2e 1.5.0.20140606-0033), you can only configure m2e to preserve additional classpath entries, but it will always clobber the ones that it automatically generates. This includes the classpath entry for the JRE, so there is no way to set this entry manually and have it survive an m2e project update.
You need to configure Maven to use the correct JRE.
What you're doing is you configured Eclipse to use a certain JRE and now you expect Maven to use the same. This doesn't work because Maven will use the POM (pom.xml) to determine which JRE to use. That makes sense since Maven is a command line tool which runs outside of Eclipse. m2e just configures Eclipse to behave similarly as Maven from the command line. As you can see, Maven is in control here, Eclipse is not!
To make the two work with each other, you need to configure the Maven compiler plugin like so:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source> <!-- JRE version that you need -->
<target>1.8</target>
</configuration>
</plugin>
That will tell Maven which JRE version you want. Now you can configure a matching JRE version in Eclipse preferences and m2e will configure the Eclipse compiler to use the one which has the correct version.

Use snapshot library when developing a web app in eclipse

I develop a web application using eclipse, maven and tomcat container. My web app uses snapshot version of a Java library that I also work on. In eclipse both projects (web app and the library) are open. The library is a regular Maven/Java project, and the web app is a Dynamic Web Application.
The problem is that eclipse under Maven Dependencies displays the library project as open, and not the jar files, so when I want to debug the web app the jar of that library is not copied into the WEB-INF/lib folder of tomcat. If I use a release version of the library, eclipse displays the jar file and is copied into the WEB-INF/lib folder of tomcat.
To solve that problem I have to close the library project and it works as expected (jar copied into tomcat). Is there a way to include an open project into a dynamic web app when debugging it with tomcat under eclipse?
.classpath:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java"/>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v6.0"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
I am not sure if it works in web projects but
<project> -> context menu -> Maven -> Disable Workspace Resolution
will stop the m2eclipse plugin to resolve dependencies in the workspace (by checking open projects). The dependencies will be requested from the (local) repository instead. Thus you have to install your library project if you want a new version to be referenced by your web project.

Categories