Search code examples
javaspring-bootkotlingoogle-cloud-platformspring-cloud

Multiple Spring Cloud GCP libraries in single project causes NoClassDefFoundError


If I use a single Spring Cloud GCP library e.g. implementation("org.springframework.cloud:spring-cloud-gcp-starter-sql-postgresql:1.1.1.RELEASE") and the property: spring.cloud.gcp.credentials.encoded-key= for credentials... everything works fine.

But if I also want to say add pub/sub to my project via: implementation("org.springframework.cloud:spring-cloud-gcp-starter-pubsub:1.1.3.RELEASE") then I get the exception below.

I have tried:

  1. Using different Java versions 11 and 12
  2. Different Spring Cloud GCP libraries as the "second" library implementation("org.springframework.cloud:spring-cloud-gcp-starter:1.1.3.RELEASE") and implementation("org.springframework.cloud:spring-cloud-gcp-starter-logging:1.1.3.RELEASE")
  3. Using spring.cloud.gcp.credentials.location instead of spring.cloud.gcp.credentials.encoded-key
  4. Use admin service account to make sure it's not a IAM role issue.

implementation("org.springframework.cloud:spring-cloud-gcp-starter:1.1.3.RELEASE") and implementation("org.springframework.cloud:spring-cloud-gcp-starter-logging:1.1.3.RELEASE")

As soon as I include more than one of these Spring Cloud GCP libraries, the same SocketFactory error comes up without fail. From the docs, it should work fine. The second library should just use the same credentials.

If I revert back to a single library then it works fine.

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.autoconfigure.jdbc.DataSourceProperties]: Factory method 'cloudSqlDataSourceProperties' threw exception; nested exception is java.lang.NoClassDefFoundError: com/google/cloud/sql/core/CoreSocketFactory
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:622) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
    ... 171 common frames omitted
Caused by: java.lang.NoClassDefFoundError: com/google/cloud/sql/core/CoreSocketFactory
    at org.springframework.cloud.gcp.autoconfigure.sql.GcpCloudSqlAutoConfiguration$CloudSqlDataSourcePropertiesConfiguration.cloudSqlDataSourceProperties(GcpCloudSqlAutoConfiguration.java:209) ~[spring-cloud-gcp-autoconfigure-1.1.3.RELEASE.jar:1.1.3.RELEASE]
    at org.springframework.cloud.gcp.autoconfigure.sql.GcpCloudSqlAutoConfiguration$CloudSqlDataSourcePropertiesConfiguration$$EnhancerBySpringCGLIB$$4f5495da.CGLIB$cloudSqlDataSourceProperties$0(<generated>) ~[spring-cloud-gcp-autoconfigure-1.1.3.RELEASE.jar:1.1.3.RELEASE]
    at org.springframework.cloud.gcp.autoconfigure.sql.GcpCloudSqlAutoConfiguration$CloudSqlDataSourcePropertiesConfiguration$$EnhancerBySpringCGLIB$$4f5495da$$FastClassBySpringCGLIB$$58c2377.invoke(<generated>) ~[spring-cloud-gcp-autoconfigure-1.1.3.RELEASE.jar:1.1.3.RELEASE]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.1.4.RELEASE.jar:5.1.4.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363) ~[spring-context-5.1.4.RELEASE.jar:5.1.4.RELEASE]
    at org.springframework.cloud.gcp.autoconfigure.sql.GcpCloudSqlAutoConfiguration$CloudSqlDataSourcePropertiesConfiguration$$EnhancerBySpringCGLIB$$4f5495da.cloudSqlDataSourceProperties(<generated>) ~[spring-cloud-gcp-autoconfigure-1.1.3.RELEASE.jar:1.1.3.RELEASE]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[na:na]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
    ... 172 common frames omitted
Caused by: java.lang.ClassNotFoundException: com.google.cloud.sql.core.CoreSocketFactory
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583) ~[na:na]
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na]
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
    ... 183 common frames omitted

I have also created a Github Issue here: https://github.com/spring-cloud/spring-cloud-gcp/issues/1948


Solution

  • Different versions of the libraries were used due to copy-paste import from Maven Central without checking versions.

    Versions used included 1.1.1.RELEASE and 1.1.3.RELEASE. Only one of those release numbers should have been used at a time.

    Refactored code to remove posibility of this error:

    implementation("org.springframework.cloud:spring-cloud-gcp-starter-sql-postgresql:$springCloudGCPVersion")
    implementation("org.springframework.cloud:spring-cloud-gcp-starter-pubsub:$springCloudGCPVersion")
    implementation("org.springframework.cloud:spring-cloud-gcp-dependencies:$springCloudGCPVersion")
    implementation("org.springframework.cloud:spring-cloud-gcp-starter:$springCloudGCPVersion")