How to Fix `java.lang.NoSuchMethodError: org.apache.commons.cli.CommandLine.hasOption` in Apache Flink
When running Apache Flink, you might encounter the following error message during startup or execution:
1 | java.lang.NoSuchMethodError: org.apache.commons.cli.CommandLine.hasOption |
For example, when I use Flink version 1.17.2 and start a job in Application Mode, the job is submitted successfully and runs as expected. The command and output information are as follows.
1 | $ /data/flink/flink-1.17.2/bin/flink run-application -t yarn-application -p 3 -Djobmanager.memory.process.size=1024m -Dtaskmanager.memory.process.size=2048m -Dtaskmanager.memory.network.max=64mb -c com.my.flink.etl.dws.trd.OrderSummaryJob -Dyarn.application.name="com.my.flink.etl.dws.trd.OrderSummaryJob" -Dyarn.application.type="Flink 1.17.2" /data/flink/my-flink-etl-jar/dws-trd-ord-summary.jar |
Now, I want to test the savepoint feature and observe the job’s behavior when stopping and restarting it. However, when executing the Flink command (to submit a job and specify a savepoint to resume from), I encounter the following error. The same issue also occurs when running flink stop
.
1 | /data/flink/flink-1.17.2/bin/flink run-application -t yarn-application -p 3 -Djobmanager.memory.process.size=1024m -Dtaskmanager.memory.process.size=2048m -Dtaskmanager.memory.network.max=64mb -c com.my.flink.etl.dws.trd.OrderSummaryJob -Dyarn.application.name="com.my.flink.etl.dws.trd.OrderSummaryJob" -Dyarn.application.type="Flink 1.17.2" -s hdfs:/flink-checkpoints/flink-1.17.2/ea98ue43a2fc63d4631895af4604dd43e/chk-102 /data/flink/my-flink-etl-jar/dws-trd-ord-summary.jar |
This error typically indicates an issue with version conflicts or the availability of the required method within the libraries that Flink is using. In this case, the error is related to the Apache Commons CLI library, which is used by Flink for command-line argument parsing.
In this article, we will walk through the possible causes and solutions for this error, so you can get your Flink application up and running.
Understanding the Error
The error java.lang.NoSuchMethodError
suggests that at runtime, your application is trying to invoke a method that is not present in the version of the library being used. The method in question is hasOption
, which belongs to the CommandLine
class of the Apache Commons CLI library.
Flink internally relies on Apache Commons CLI for parsing command-line options, and it expects a specific version of the library. However, if there’s a version mismatch between the library that Flink was compiled against and the one available at runtime, the hasOption
method might not exist, causing the error.
Common Causes of the Error
There are a few potential causes for this error:
- Version Conflict with Apache Commons CLI: If your project uses a different version of the Apache Commons CLI library than what Flink expects, the
hasOption
method might not exist or could be defined differently. - Incompatible Dependencies: Other libraries in your project might bring in a different version of the Apache Commons CLI library, which could override the version expected by Flink.
- Incorrect Classpath Configuration: If your Flink setup includes additional or outdated versions of libraries that conflict with the ones included in the Flink distribution, it could result in runtime issues like this.
- Missing related jar packages.
Solutions to Resolve the Issue
Verify That the commons-cli Jar Package Exists
Given that the error is a java.lang.NoSuchMethodError
, it’s likely due to a missing JAR file. Navigate to the lib
directory under the Flink installation folder, as shown below, and you’ll find that the common-cli
JAR is indeed missing. To fix this, simply download the JAR and place it in the lib
directory.
1 | $ ll lib/ |
You can download the JAR file using the following command:
1 | wget https://repo1.maven.org/maven2/commons-cli/commons-cli/1.5.0/commons-cli-1.5.0.jar |
Ensure Flink and Library Version Compatibility
The first step is to verify that you are using a compatible version of Flink and Apache Commons CLI. Apache Flink uses a specific version of Apache Commons CLI, and running Flink with an incompatible version can lead to errors.
- Check Flink Version: Find out which version of Flink you are using and check the corresponding version of Apache Commons CLI in its dependencies.
- You can check the Flink version by running
flink --version
. - Flink dependencies, including Apache Commons CLI, are often specified in the
pom.xml
(for Maven-based builds) orbuild.gradle
(for Gradle-based builds).
- You can check the Flink version by running
- Ensure Correct Version of Apache Commons CLI: If Flink relies on a specific version of Commons CLI, make sure your project includes the same version.For example, if you’re using Maven, you can specify the dependency version explicitly:
1 | <dependency> |
Exclude Conflicting Dependencies
If your project or any of the libraries you’re using brings in a conflicting version of Apache Commons CLI, you can exclude it from your dependencies.
For example, in Maven, you can exclude a conflicting dependency like this:
1 | <dependency> |
This will prevent the conflicting version of the library from being included, allowing Flink to use its bundled version of Commons CLI.
In Gradle, you can exclude a dependency in a similar manner:
1 | dependencies { |
Update Dependencies to Latest Versions
Sometimes the issue arises due to the use of outdated or unsupported versions of libraries. Ensure all dependencies in your project are up to date, particularly Apache Commons CLI and Flink.
To update dependencies in Maven, run:
1 | mvn versions:display-dependency-updates |
In Gradle, use:
1 | ./gradlew dependencyUpdates |
This will show you if any of your dependencies are outdated and need to be updated to a compatible version.
Review Classpath Configuration
Ensure that your classpath is correctly configured to prioritize Flink’s bundled dependencies and avoid conflicts. This is particularly important if you are running Flink in a distributed environment, as the classpath needs to be consistent across all nodes in the cluster.
If you’re running Flink in standalone mode, make sure your job’s JAR file contains the correct dependencies, or use the Flink lib/
directory to place compatible versions of libraries.
Final Thoughts
The error java.lang.NoSuchMethodError: org.apache.commons.cli.CommandLine.hasOption
in Flink is often caused by a version mismatch or classpath conflict related to Apache Commons CLI. To fix the issue:
- Verify that the commons-cli jar package exists.
- Ensure you’re using the correct version of Flink and Apache Commons CLI.
- Exclude conflicting dependencies from your project.
- Update your project’s dependencies to compatible versions.
- Review your classpath to prevent conflicts at runtime.
By following these steps, you should be able to resolve the error and get your Flink application running smoothly again. If the problem persists, reviewing Flink’s official documentation or community forums might provide additional insights specific to your Flink version and environment.