# Troubleshooting
## Logging
Our libraries use the Java logging API via `java.util.logging` package.
Configuring logging level reveals various facts that help your troubleshooting,
including:
- The timing of underlying client-server communication
- Request and response message headers
- Verbose messages in underlying dependency libraries
While there are various ways to configure the logging,
to quickly enable verbose logging for the Google Cloud Java libraries, create
a file `logging.properties` with the following content:
```
# run java program pointing to this properties file with the java arg
# -Djava.util.logging.config.file=path/to/logging.properties
handlers=java.util.logging.ConsoleHandler
java.util.logging.SimpleFormatter.format=%1$tF %1$tT,%1$tL %4$-8s %3$-50s - %5$s %6$s%n
# --- ConsoleHandler ---
java.util.logging.ConsoleHandler.level=ALL
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
.level=INFO
# --- Specify logging level for certain packages ---
# com.google.api is for HTTP 1.1 layer
com.google.api.level=ALL
# io.grpc is for gRPC + Netty layer
io.grpc.level=FINE
# com.google.auth is for authentication
com.google.auth.level=FINE
# Example when we want to specify storge library's level. This works when
# the target Cloud library uses the logging API.
com.google.cloud.storage.level=INFO
```
and run your application with `-Djava.util.logging.config.file=path/to/logging.properties`
as the "VM argument" (not "Program argument").
If you use IntelliJ, you specify the VM argument in "Run/Debug Configuration":

If the JVM of your program is running with the configuration correctly, you see
the FINE-level logging in your console. Example output:
```
2023-04-05 13:03:01,761 FINE com.google.auth.oauth2.DefaultCredentialsProvider - Attempting to load credentials from well known file: /usr/local/google/home/suztomo/.config/gcloud/application_default_credentials.json
2023-04-05 13:03:01,847 FINE io.grpc.ManagedChannelRegistry - Unable to find OkHttpChannelProvider
java.lang.ClassNotFoundException: io.grpc.okhttp.OkHttpChannelProvider
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:315)
...
```
Note that you may see many stacktraces printed there.
As long as it's "FINE" level, they are not errors.
This is just one way to configure logging level.
For more details about Java logging API usage, see [Java Logging Overview](
https://docs.oracle.com/javase/8/docs/technotes/guides/logging/overview.html).
## ALPN is not configured properly
If you see exceptions related to `ALPN is not configured properly`, such as:
```
Caused by: java.lang.IllegalArgumentException: ALPN is not configured properly. See https://github.com/grpc/grpc-java/blob/master/SECURITY.md#troubleshooting for more information.
```
Please use the [compatibility checker](https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-util/google-cloud-compat-checker) to see if your environment is compatible with grpc-based clients. The incompatibility can mean that:
- You are not on a [supported platform](https://github.com/googleapis/google-cloud-java/#supported-platforms).
- There are classpath conflicts with `netty`.
- Or, you are seeing any of the conflicts specified in [gRPC Troubleshooting guide](https://github.com/grpc/grpc-java/blob/master/SECURITY.md#troubleshooting).
## ClassNotFoundException, NoSuchMethodError, NoClassDefFoundError
These errors are usually caused by having multiple versions or conflicting versions of the same dependency in the classpath.
Usually these dependency conflicts occur with `guava` or `protobuf-java`.
There may be multiple sources for classpath conflicts:
- Multiple versions of the same transitive dependency in the dependency tree
- Your runtime classpath has different versions of dependencies than what you specified in the build
For example, if you have a direct or a transitive dependency on Guava version 19.0,
and `google-cloud-java` uses Guava version 30.0,
then `google-cloud-java` could be using Guava methods that don't exist in Guava 19.0,
and cause `NoSuchMethodError`.
Similarily, if your classpath has an older version of `protobuf-java`,
but `google-cloud-java` requires a newer version,
then you might see `NoClassDefFoundError` that fails to initialize `google-cloud-java` classes. For example:
```
java.lang.NoClassDefFoundError: Could not initialize class com.google.pubsub.v1.PubsubMessage$AttributesDefaultEntryHolder
```
### Validate the conflict
Check the dependency tree to see if you have multiple versions of the same dependencies:
```
$ mvn dependency:tree
```
Look for versions of potentially conflicting dependencies like `guava`, `protobuf-java`, etc.
If you experience the error only during runtime, then your runtime environment
might be introducing conflicting JARs into your runtime classpath. A typical case
is that Hadoop, Spark, or other server software that your application runs on
has conflicting versions `netty`, `guava`, or `protobuf-java` JARs in the classpath.
### Detecting conflicts during build
To detect dependency linkage errors at compile time, add the
[Linkage Checker Enforcer Rule](https://github.com/GoogleCloudPlatform/cloud-opensource-java/tree/master/enforcer-rules)
in your pom.xml:
```
org.apache.maven.plugins
maven-enforcer-plugin
3.0.0-M3
com.google.cloud.tools
linkage-checker-enforcer-rules
1.5.7
enforce-linkage-checker
verify
enforce
```
There is no way to detect runtime classpath conflicts though. You need to be fully
aware of which JARs/classes are included in the runtime classpath
as every server environment is different.
### Resolving the conflict
There are different strategies to resolve conflicts, but you must understand the root cause of the conflicts. For example:
- If you have control over the dependency tree, upgrade
offending dependencies (for example, upgrading Guava version). This is the
least hackish approach, but it is a lot of work that can require multiple releases
of multiple libraries to sync everything up.
- If you can't modify and push new versions of your dependencies, import
`com.google.cloud:libraries-bom:25.1.0` (or a more recent version) and use that to
select consistent dependency versions. This is the easiest route.
For example, this is how you can depend on consistent versions of Guava and
`com.google.cloud:google-cloud-storage` without explicitly setting the version of either one:
```
...
com.google.cloud
libraries-bom
25.1.0
pom
import
...
com.google.cloud
google-cloud-storage
com.google.guava
guava
...
...
```
- If changing dependency versions causes other failures,
consider [shading dependencies](https://maven.apache.org/plugins/maven-shade-plugin/)
that conflict with `google-cloud-java`.
For example, to shade `guava` and `protobuf-java`:
```
org.apache.maven.plugins
maven-shade-plugin
...
package
shade
false
com.google.protobuf
myapp.shaded.com.google.protobuf
com.google.common
myapp.shaded.com.google.common
```