Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HikariCP and c3po dependencies are in the compile scope #294

Closed
markkolich opened this issue Dec 22, 2018 · 8 comments
Closed

HikariCP and c3po dependencies are in the compile scope #294

markkolich opened this issue Dec 22, 2018 · 8 comments

Comments

@markkolich
Copy link

markkolich commented Dec 22, 2018

I upgraded my project from Quartz 2.2.3 to 2.3.0 and suddenly started seeing this build failure from the Maven duplicate finder plugin, complaining of duplicate HikariCP classes on my classpath:

[WARNING] Found duplicate and different classes in
  [com.zaxxer:HikariCP-java6:2.3.13, com.zaxxer:HikariCP:3.2.0]:
[WARNING]   com.zaxxer.hikari.HikariConfig
[WARNING]   com.zaxxer.hikari.HikariConfigMXBean
[WARNING]   com.zaxxer.hikari.HikariDataSource
[WARNING]   com.zaxxer.hikari.HikariJNDIFactory
[WARNING]   com.zaxxer.hikari.hibernate.HikariConfigurationUtil
[WARNING]   com.zaxxer.hikari.hibernate.HikariConnectionProvider
[WARNING]   com.zaxxer.hikari.metrics.MetricsTracker
[WARNING]   com.zaxxer.hikari.pool.HikariPool
[WARNING]   com.zaxxer.hikari.util.ConcurrentBag
[WARNING]   com.zaxxer.hikari.util.DriverDataSource
[WARNING]   com.zaxxer.hikari.util.FastList
[WARNING]   com.zaxxer.hikari.util.JavassistProxyFactory
[WARNING]   com.zaxxer.hikari.util.UtilityElf

My Java 11 project directly uses com.zaxxer:HikariCP:3.2.0 and I was surprised that a dependency was transitively pulling in com.zaxxer:HikariCP-java6:2.3.13.

With a little digging, it looks like @jhouserizer added a hard compile time dependency on com.zaxxer:HikariCP-java6 under #126 which is the source of the duplicate classes:

[INFO] +- org.quartz-scheduler:quartz:jar:2.3.0:compile
[INFO] |  +- com.mchange:c3p0:jar:0.9.5.2:compile
[INFO] |  +- com.mchange:mchange-commons-java:jar:0.2.11:compile
[INFO] |  \- com.zaxxer:HikariCP-java6:jar:2.3.13:compile

I could be wrong, but is com.zaxxer:HikariCP-java6 (and the others) really required to use the Quartz scheduler? These dependencies appear to only be required if you intend to use a Quartz data source backed by an SQL database. For applications that are not using these features of Quartz, aren't these dependencies unnecessary?

If so, shouldn't Quartz declare these "optional" run-time dependencies in the Maven provided or optional scope? Placing them in the compile scope forces consumers of Quartz to add exclusions in order to keep such conflicts out of the classpath. I would expect that if Quartz consumers need to use a DB data source in conjunction with a scheduler, then it should be on them to explicitly "provide" a compatible version of HikariCP (or c3p0 for that matter).

E.g., from https://maven.apache.org/pom.html#Dependency_Version_Requirement_Specification perhaps quartz-core/pom.xml should have declared such dependencies as:

<dependency>
  <groupId>com.zaxxer</groupId>
  <artifactId>HikariCP-java6</artifactId>
  <version>[2.3.13,)</version>
  <scope>provided</scope>
</dependency>

Fwiw, @enwired had the same concern documented here #126 (comment).

@zemian
Copy link
Contributor

zemian commented Dec 27, 2018

Hi @markkolich Thanks for reporting this issue.

We added HikariCP-java6 to quartz-2.2.x series because we needed JDK6 compatible library. The quartz-2.3.x should have upgraded to HikariCP-java7 since that branch is required JDK7. But unfortunately quartz-2.3.0 was released without this fix.

To resolve your issue, you can try 2 options:

  1. You can try add quartz-2.3.0 to your project that exclude the HikariCP-java6 like this:
        <dependency>
          <groupId>org.quartz-scheduler</groupId>
          <artifactId>quartz</artifactId>
          <version>2.3.0</version>
          <exclusions>
            <exclusion>
              <groupId>com.zaxxer</groupId>
              <artifactId>HikariCP-java6</artifactId>
            </exclusion>
          </exclusions>
        </dependency>
  1. You can can use quartz-2.4.x branch and it's using latest HikariCP that requires JDK8. But we have not release any version from this branch yet, so you have to build it on your own.

Zemian

@zemian
Copy link
Contributor

zemian commented Dec 28, 2018

Fixed in e0a1c79

@zemian zemian closed this as completed Dec 28, 2018
@markkolich
Copy link
Author

@zemian Thanks for the followup. However, I don't directly see how e0a1c79 addresses this specific concern.

Can you kindly clarify how these are related?

@zemian
Copy link
Contributor

zemian commented Dec 28, 2018

Hi @markkolich , sorry I posted the wrong commit. It should be b194911 That's the commit that I added hikaricp JDK8 compatible on quartz-2.4.x branch, which is the option#2 solution I mentioned above.

As I also mentioned in previous comment with option#1, you do have workaround to even use older release.

@markkolich
Copy link
Author

@zemian thanks for the correction.

I see that you upgraded HikariCP to 3.2.0 in commit b194911.

However, I think my original concern still stands:

HikariCP and c3p0 are still in the compile scope. These are not "required" to use Quartz correct? They are effectively optional runtime dependencies if I understand their usage correctly. If so, shouldn't these dependencies be placed in the provided or optional scope within the Quartz pom itself?

In other words, if I don't intend to use these features of Quartz (to interact with a database), do I still need these dependencies at all? Yes, I can add an exclusion in my pom, but that pushes the problem onto the user/consumer of Quartz.

I think a much cleaner solution is to tell the users of this library "if you need to interact with a database, then you should add HikariCP to your pom". Or, "add c3p0 to your pom". Then in the Quartz pom, put these database dependencies in the provided scope with a version identifier that enforces a minimum provided version:

<dependency>
  <groupId>com.zaxxer</groupId>
  <artifactId>HikariCP</artifactId>
  <version>[2.3.0)</version>
  <scope>provided</scope>
</dependency>

In short, with this approach, if I want to use Quartz and I need Quartz to interact with a database, in my pom I will provide a compatible version of either HikariCP or c3p0.

@zemian
Copy link
Contributor

zemian commented Dec 28, 2018

Hi @markkolich yes you are correct and the suggestion is good one too. I created a separate issue #306 as feature request for this.

As it stand, the current Quartz made a conciseness choice (or in past) that coupled the two DB pool impl as static compile dependence. For convenience purpose I am sure. Not much we can do with those released artifacts. Maybe we can try to improve it in future.

@niaggarw
Copy link

Hi @zemian,

Thanks for all the information you provided. I am still facing an issue regarding this setup. I am using the following versions:
Hikari cp: 3.1.0
Quartz: 2.4.0
java 8

My quartz.properties file looks like:
org.quartz.dataSource.DS.driver = com.mysql.cj.jdbc.Driver
org.quartz.dataSource.DS.URL = jdbc:mysql://127.0.0.1:3306/db51?useOldAliasMetadataBehavior=true&rewriteBatchedStatements=true
org.quartz.dataSource.DS.user =root
org.quartz.dataSource.DS.password =root
hibernate.dialect=org.hibernate.dialect.MySQL57InnoDBDialect
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.dataSource.DS.testQuery = select now()
org.quartz.dataSource.DS.testConnection= false
org.quartz.dataSource.DS.readReplica.URL = jdbc:mysql://127.0.0.1:3306/db51?useOldAliasMetadataBehavior=true
org.quartz.dataSource.DS.connectionProvider.class=org.quartz.utils.HikariCpPoolingConnectionProvider

My queries are:

  1. Do i need HikariCp-java jar as well, if yes then which version of this jar will work with my setup?
  2. I am getting an error continuously despite of trying everything you mentioned is

Error creating bean with name 'schedulerFactoryBean' defined in ServletContext resource [/WEB-INF/servlet.xml]: Invocation of init method failed; nested exception is org.quartz.SchedulerException: ConnectionProvider class 'org.quartz.utils.HikariCpPoolingConnectionProvider' could not be instantiated. [See nested exception: java.lang.InstantiationException: org.quartz.utils.HikariCpPoolingConnectionProvider]

Kindly Suggest.

@sabuj-das
Copy link

For me, it is solved by following this comment #126 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants