I have a package which is a JNI wrapper around native code and is therefore platform dependent. I want to create a platform specific jar using os-maven-plugin. The relevant part of my pom is as follows:
<groupId>foo.bar.baz</groupId>
<artifactId>project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.1</version>
</extension>
</extensions>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<classifier>${os.detected.classifier}</classifier>
</configuration>
</plugin>
</plugins>
// ...
After running mvn clean install, it seems the artifact is built appropriately:
$ ls /Users/erip/.m2/repository/foo/bar/baz/project/0.0.1-SNAPSHOT
_remote.repositories project-0.0.1-SNAPSHOT-osx-x86_64.jar
maven-metadata-local.xml project-0.0.1-SNAPSHOT.pom
however, when I add this dependency to my gradle file…
repositories {
// ...
mavenLocal()
}
dependencies {
// ...
compile 'foo.bar.baz:project:0.0.1-SNAPSHOT:osx-x86_64'
}
and try to build, gradle says it can’t find the file:
$ ./gradlew clean build
> Task :compileJava FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':compileJava'.
> Could not resolve all files for configuration ':compileClasspath'.
> Could not find foo.bar.baz:project:0.0.1-SNAPSHOT.
Searched in the following locations:
...
- file:/Users/erip/.m2/repository/foo/bar/baz/project/0.0.1-SNAPSHOT/project-0.0.1-SNAPSHOT.pom
Required by:
project :
It looks in an existing pom, but fails to resolve the jar, so why can't gradle find this dependency?
Resolving dependencies with classifiers is currently not supported by Gradle as of 6.8 as corroborated by this issue.
Re os-maven-plugin: The Java System Properties:
os.name
os.arch
os.version
are available in POMs. Aren't these enough for your artifact classifiers?
Re your not found dependency: The Gradle dependencies doc mentions classifiers just in conjunction with JavaScript. The examples for dependencies there use just <groupId>:<artifactId>:<version>. (Where did you get the 3-colon syntax with the additional :<classifier>?) The POM Reference mentions classifiers/qualifiers as part of the version, so I'd try:
dependencies {
// ...
compile 'foo.bar.baz:project:0.0.1-SNAPSHOT-osx-x86_64'
}
Related
During working on project arch4u-pmd we made several java-based pmd rules, configured them in XML-based ruleset our-rules.xml, and published it as a plain java lib/artifact (io.github.abc:my-pmd-rules:0.1.0) to our artifacts repository.
The artifact structure looks like this:
> unzip -l my-pmd-rules-0.1.0.jar
Archive: my-pmd-rules-0.1.0.jar
Length Date Time Name
--------- ---------- ----- ----
0 02-15-2022 00:24 META-INF/
139 02-15-2022 00:24 META-INF/MANIFEST.MF
0 02-15-2022 00:24 io/
0 02-15-2022 00:24 io/github/
0 02-15-2022 00:24 io/github/rules/
...
4781 02-15-2022 00:24 io/github/rules/MissingMandatoryAnnotation.class
...
1138 02-15-2022 00:24 io/github/rules/our-rules.xml
...
How we can add them to the Gradle project using pmd plugin?
We have to process the following materials/questions/answers:
https://stackoverflow.com/search?page=2&tab=Relevance&q=pmd%20classpath
ClassNotFoundException: Using custom java rule for PMD ruleset
Gradle's PMD plugin: what are acceptable arguments?
Adding a ruleset to PMD?
Adding custom rules in PMD - class not found issue
https://discuss.gradle.org/t/pmd-ruleset-not-available-in-classpath/7201
https://discuss.gradle.org/t/custom-rules-with-pmd-plugin/5859/4
How to configure PMD Auxiliary classpath in Sonar
https://docs.gradle.org/current/userguide/pmd_plugin.html
https://github.com/gradle/gradle/blob/master/subprojects/code-quality/src/main/groovy/org/gradle/api/plugins/quality/PmdPlugin.java
Custom PMD rule with Gradle also don't work
tasks.withType(Pmd) {
pmdClasspath += file("path/to/rules.jar")
}
In official docs for Gradle pmd plugin there is a dependency section that explains this aspect on high-level without a real example:
pmd - The PMD libraries to use
pmdAux - The additional libraries that are available for type resolution during analysis. This might be useful if PMD complains about missing classes.
In order to add the custom java rules to your project
Using Gradle plugin
apply plugin: 'pmd'
repositories {
mavenCentral() // if your rules in Maven Central
mavenLocal() // if your rules is in .m2 folder
maven {
// if your rules are in some custom/self-hosted artifacts repository like Nexus
}
}
dependencies {
...
pmd "io.github.abc:my-pmd-rules:0.1.0"
pmd "commons-io:commons-io:2.11.0" // required dependency by pmd engine
...
}
pmd {
consoleOutput = true
ruleSetFiles = files("io/github/rules/our-rules.xml") // exactly path as in your lib classpath
ruleSets = [] // Keep it as is, workaround for pmd
}
Using Maven plugin
...
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.15.0</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<printFailingErrors>true</printFailingErrors>
<rulesets>
...
<ruleset>io/github/rules/our-rules.xml</ruleset> <!-- exactly path as in your lib classpath -->
...
</rulesets>
<excludeRoots>
<excludeRoot>target/generated-sources/</excludeRoot>
</excludeRoots>
</configuration>
<dependencies>
<!-- your custom rules -->
<dependency>
<groupId>io.github.abc</groupId>
<artifactId>my-pmd-rules</artifactId>
<version>0.1.0</version>
</dependency>
</dependencies>
</plugin>
...
</plugins>
</build>
...
In case if you already have a ruleset and you just want to include the custom Java rule (that came from the library) you may define it directly in your ruleset xml as is:
<!-- Define a rule -->
<rule name="TheRuleName"
language="java"
externalInfoUrl="https://link.to.your.rule.official.docs.com"
message="The violation message regarding your rule"
class="io.github.rules.MissingMandatoryAnnotation">
<priority>3</priority>
<properties>
...
</properties>
</rule>
I'm learning Java. To read JSON in my application, I downloaded this JSON library; which is an automatic module.
I included that library in my module descriptor like:
module art
{
exports art.anixt;
exports art.coartl;
exports art.runeape;
requires org.json; // org.json cannot be resolved to a moduleJava(8389908)
}
My settings.json in vscode:
{
"files.exclude": {
"**/.classpath": true,
"**/.project": true,
"**/.settings": true,
"**/.factorypath": true
},
"java.format.settings.url": "Format.xml",
"java.format.settings.profile": "style",
"java.project.referencedLibraries": [
"lib/**/*.jar" // jar file showing in Referenced library(see screenshot)
]
}
How do I include the jar file in my module and import it into my Java file?
Screenshot:
TL;DR — As this unresolved 'Cannot be resolved' errors in projects with module-info.java issue reports, vscode is brain dead when it comes to JPMS and module-info.java.
The long-winded version
From my own experience, I can personally vouch for what the reporter of the above-linked vscode issue reports…
„…I've tried both Gradle and Maven…“
…
„…I find that Gradle and Maven will automatically refresh the classpath file and remove my modifications to it, which will bring back the errors…“
…
„…there needs to be module path information set in the classpath file in order for Eclipse to be happy, but there is no good way to do with that from Gradle or Maven…“
Proof that it's a vscode issue is that the exact same project — unchanged except for the removal of your comment — compiles perfectly fine in IntelliJ…
Since your project uses neither Maven nor Gradle — opting instead to use file-based dependency mgt with the jar in the lib folder — you're in even worse shape because you've eliminated the option of applying any JPMS-enabling plugins that could resolve the issue.
For example, by adding the following pom.xml with the appropriate configuration for the maven-compiler-plugin to my experimental version of your project…
…
<dependencies>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20200518</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
<compilerArgs>
<arg>-Xlint:unchecked</arg>
<arg>--add-modules</arg>
<arg>org.json</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
…
…Maven does its magic and processes the module-info.java successfully…
I've successfully resolved other Stackers' JPMS woes by helping them apply that mrJar plugin mentioned in that vscode bug report. So if you're open to using Gradle instead of Maven, I could likewise advise you on how to configure that plugin too.
I'm trying to use checkstyle and findbugs by doing mvn checkstyle:checkstyle but I have this error
This error
[ERROR] Failed to execute goal on project my-project: Could not resolve dependencies for project default:my-project:jar:1.1: Could not find artifact com.sun:tools:jar:0 at specified path C:\Program Files\Java\jdk-11.0.2/../lib/tools.jar -> [Help 1]
I do not have a tools.jar into my JDK (i have jdk-11.0.2).
I'm on it since 2H, please help :/
tools.jar removed from Java 9+
You're on JDK 11. No tools.jar found there.
JEP 220: Modular Run-Time Images removed both tools.jar and rt.jar from the lib folder, as of Java 9.
Removed: rt.jar and tools.jar
The class and resource files previously stored in lib/rt.jar,
lib/tools.jar, lib/dt.jar, and various other internal JAR files are
now stored in a more efficient format in implementation-specific files
in the lib directory. The format of these files is not specified and
is subject to change without notice.
This change is part of adding the Java Platform Module System, a.k.a. Project Jigsaw.
To upgrade Checkstyle, use later versions, such as:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.0.0</version>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>8.18</version>
</dependency>
</dependencies>
</plugin>
Notice the inner dependency block.
Consult a Maven repo for versions of Apache Maven Checkstyle Plugin and of Checkstyle.
Let's say
when you call mvn archetype:generate how does maven knows that it needs to invoke "Maven Archetype Plugin"?
Or when you do mvn dependency:copy-dependencies how does it invoke 'Apache Maven Dependency Plugin'?
i.e How does maven maintains the link between 'archetype' -> 'Maven Archetype Plugin'?
It's available by default. This page lists the core plugins and others
https://maven.apache.org/plugins/.
If you want to use other plugin, you need to mention in pom.xml file, so that the dependencies can be resolved.
<build>
<plugins>
<!--Restdocs config for collating all snippets start-->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>animal-sniffer-maven-plugin</artifactId>
<version>XXX</version>
...
</plugin>
</plugins>
</build>
If you run the command mvn animal-sniffer:check. animal-sniffer is the plugin prefix and check is the goal. The mapping between prefix and dependency is mentioned here. Meanwhile, the goal check is mapped by annotation in actual implementation, if you check the source code of this plugin, you will see something like below.
#Mojo( name = "check", defaultPhase = LifecyclePhase.PROCESS_CLASSES, requiresDependencyResolution = ResolutionScope.COMPILE, threadSafe = true )
I have added the most updated Selenium dependency in my pom.xml
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.7.1</version>
</dependency>
I ran
mvn clean install
inside the directory with my pom.xml and I have also imported the correct classes in my app class as per the Selenium documentation
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
However when i try and run my main method, I get the following error
Exception in thread "main" java.lang.NoClassDefFoundError:
org/openqa/selenium/WebDriver
I look in my ~/.m2/repository folder and I don't see an openqa folder but instead I see a seleniumhq folder.
Why didn't maven install the openqa folder, and why does the documentation say to import from org.openqa... when that never exist in my jar repository. I'm very confused, I just want to be able to import selenium Webdriver successfully while having it in my local repository.
Firstly, check properly if you have all important dependencies for your program.
Secondly, I had similar error while running maven project:
Caused by: java.lang.NoClassDefFoundError: org/openqa/selenium/JavascriptExecutor
And this problem was because of inappropriate plugin, because I tested different versions of Selenium and it didn't help me.
So when I changed maven-jar-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>your_main_class</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
to maven-shade-plugin plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>your_main_class</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
The issue was gone.
The difference between plugins you can find here.
In addition, sometimes we upgrade our libraries even with same method name. Due this different in version, we get NoClassDefFoundError or NoSuchMethodError at runtime when one library was not compatible with such an upgrade.
Java build tools and IDEs can also produce dependency reports that tell you which libraries depend on that JAR. Mostly, identifying and upgrading the library that depends on the older JAR resolve the issue.
To summarize:
try to change versions of Selenium, if it contains all dependencies;
try to add necessary dependencies if you don't have it;
try to check folder of maven if it has or not what says specific error;
try to play with plugins if nothing helps above.
NoClassDefFoundError
NoClassDefFoundError in Java occurs when Java Virtual Machine is not able to find a particular class at runtime which was available at compile time. For example, if we have resolved a method call from a class or accessing any static member of a Class and that Class is not available during run-time then JVM will throw NoClassDefFoundError.
The error you are seeing is :
Exception in thread "main" java.lang.NoClassDefFoundError:
org/openqa/selenium/WebDriver
This clearly indicates that Selenium is trying to resolve the particular class at runtime from org/openqa/selenium/WebDriver which is no more available.
As you mentioned of looking into ~/.m2/repository folder, the maven folder structure for Selenium v3.7.1 (on Windows) is as follows :
C:\Users\<user_name>\.m2\repository\org\seleniumhq\selenium\selenium-java\3.7.1
So when you see a seleniumhq folder, it is pretty much expected.
What went wrong :
From all the above mentioned points it's clear that the related Class or Methods were resolved from one source Compile Time which was not available during Run Time.
This situation occurs if there are presence of multiple sources to resolve the Classes and Methods through JDK / Maven / Gradle.
Solution :
Here are a few steps to solve NoClassDefFoundError :
While using a Build Tool e.g. Maven or Gradle, remove all the External JARs from the Java Build Path. Maven or Gradle will download and resolve all the required dependencies.
If using Selenium JARs within a Java Project add only required External JARs within the Java Build Path and remove the unused one.
While using Maven, either use <artifactId>selenium-java</artifactId> or <artifactId>selenium-server</artifactId>. Avoid using both at the same time.
Remove the unwanted other <dependency> from pom.xml
Clean you Project Workspac within your IDE periodically only to build your project with required dependencies.
Use CCleane tool to wipe away the OS chores periodically.
While you execute a Maven Project always do maven clean, maven install and then maven test.
Encountered this error in Eclipse IDE. In Eclipse go to Project properties and in Java Build Path just add selenium jars in Classpath instead of Modulepath. Then under the Project tab on the top do a Clean to remove earlier buiid and then do a Run.
Are you using an IDE or working from command line? In Eclipse for example you can force downloading all dependencies by right clicking on your project, going to Maven menu item and then selecting Update Project. Then check the "Force Update of Snapshots/Releases" checkbox.
If you are opening from command line do:
mvn clean install -U
from your project path.
This is happening because you are selecting jar files under modulepath, you should add them under class path.
org.openqa.selenium is the package in the selenium-api-{version}.jar under the seleniumhq\selenium\selenium-api folder.
org.openqa.selenium.firefox is the package in the selenium-firefox-driver-{version}.jar under the seleniumhq\selenium\selenium-firefox-driver folder.
So there is no openqa folder, it's just the package name under the seleniumhq folder, you should have a check into these jar.
It's hard to say what caused NoClassDefFoundError exception without project structure and code detail. The exception is not the same as ClassNotFoundException. Maybe this answer https://stackoverflow.com/a/5756989/5374508 would be helpful.
What worked for me was to add this dependency to pom.xml:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>25.0-jre</version>
</dependency>
I was getting below error from past 2 days and what helped me was to remove all the selenium extra dependencies like selenium-support, selenium-chrome-driver etc and only keeping the below dependencies in POM file.
Error:-
java.lang.NoClassDefFoundError: org/openqa/selenium/HasAuthentication
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
Dependencies in the pom file after removing all other:-
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.1.1</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.4.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Have encountered this issue while running selenium test in eclipse IDE.
Navigate to following path:
1.Properties >> Java build path >> Libraries.
2.Add all selenium jars in Classpath instead of Modulepath.
3.Apply and close modal.
4.Now go to build path and click on "Configure Build Path".
5.Now run the selenium test.