xref: /aosp_15_r20/external/google-cloud-java/TROUBLESHOOTING.md (revision 55e87721aa1bc457b326496a7ca40f3ea1a63287)
1*55e87721SMatt Gilbride# Troubleshooting
2*55e87721SMatt Gilbride
3*55e87721SMatt Gilbride## Logging
4*55e87721SMatt Gilbride
5*55e87721SMatt GilbrideOur libraries use the Java logging API via `java.util.logging` package.
6*55e87721SMatt GilbrideConfiguring logging level reveals various facts that help your troubleshooting,
7*55e87721SMatt Gilbrideincluding:
8*55e87721SMatt Gilbride
9*55e87721SMatt Gilbride- The timing of underlying client-server communication
10*55e87721SMatt Gilbride- Request and response message headers
11*55e87721SMatt Gilbride- Verbose messages in underlying dependency libraries
12*55e87721SMatt Gilbride
13*55e87721SMatt GilbrideWhile there are various ways to configure the logging,
14*55e87721SMatt Gilbrideto quickly enable verbose logging for the Google Cloud Java libraries, create
15*55e87721SMatt Gilbridea file `logging.properties` with the following content:
16*55e87721SMatt Gilbride
17*55e87721SMatt Gilbride```
18*55e87721SMatt Gilbride# run java program pointing to this properties file with the java arg
19*55e87721SMatt Gilbride#   -Djava.util.logging.config.file=path/to/logging.properties
20*55e87721SMatt Gilbridehandlers=java.util.logging.ConsoleHandler
21*55e87721SMatt Gilbridejava.util.logging.SimpleFormatter.format=%1$tF %1$tT,%1$tL %4$-8s %3$-50s - %5$s %6$s%n
22*55e87721SMatt Gilbride
23*55e87721SMatt Gilbride# --- ConsoleHandler ---
24*55e87721SMatt Gilbridejava.util.logging.ConsoleHandler.level=ALL
25*55e87721SMatt Gilbridejava.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
26*55e87721SMatt Gilbride.level=INFO
27*55e87721SMatt Gilbride
28*55e87721SMatt Gilbride# --- Specify logging level for certain packages ---
29*55e87721SMatt Gilbride# com.google.api is for HTTP 1.1 layer
30*55e87721SMatt Gilbridecom.google.api.level=ALL
31*55e87721SMatt Gilbride# io.grpc is for gRPC + Netty layer
32*55e87721SMatt Gilbrideio.grpc.level=FINE
33*55e87721SMatt Gilbride# com.google.auth is for authentication
34*55e87721SMatt Gilbridecom.google.auth.level=FINE
35*55e87721SMatt Gilbride
36*55e87721SMatt Gilbride# Example when we want to specify storge library's level. This works when
37*55e87721SMatt Gilbride# the target Cloud library uses the logging API.
38*55e87721SMatt Gilbridecom.google.cloud.storage.level=INFO
39*55e87721SMatt Gilbride```
40*55e87721SMatt Gilbride
41*55e87721SMatt Gilbrideand run your application with `-Djava.util.logging.config.file=path/to/logging.properties`
42*55e87721SMatt Gilbrideas the "VM argument" (not "Program argument").
43*55e87721SMatt Gilbride
44*55e87721SMatt GilbrideIf you use IntelliJ, you specify the VM argument in "Run/Debug Configuration":
45*55e87721SMatt Gilbride
46*55e87721SMatt Gilbride![Screenshot of IntelliJ configuration](docs/logging_vm_options.png)
47*55e87721SMatt Gilbride
48*55e87721SMatt GilbrideIf the JVM of your program is running with the configuration correctly, you see
49*55e87721SMatt Gilbridethe FINE-level logging in your console. Example output:
50*55e87721SMatt Gilbride
51*55e87721SMatt Gilbride```
52*55e87721SMatt Gilbride2023-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
53*55e87721SMatt Gilbride2023-04-05 13:03:01,847 FINE     io.grpc.ManagedChannelRegistry                     - Unable to find OkHttpChannelProvider
54*55e87721SMatt Gilbridejava.lang.ClassNotFoundException: io.grpc.okhttp.OkHttpChannelProvider
55*55e87721SMatt Gilbride	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
56*55e87721SMatt Gilbride	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
57*55e87721SMatt Gilbride	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
58*55e87721SMatt Gilbride	at java.base/java.lang.Class.forName0(Native Method)
59*55e87721SMatt Gilbride	at java.base/java.lang.Class.forName(Class.java:315)
60*55e87721SMatt Gilbride...
61*55e87721SMatt Gilbride```
62*55e87721SMatt Gilbride
63*55e87721SMatt GilbrideNote that you may see many stacktraces printed there.
64*55e87721SMatt GilbrideAs long as it's "FINE" level, they are not errors.
65*55e87721SMatt Gilbride
66*55e87721SMatt GilbrideThis is just one way to configure logging level.
67*55e87721SMatt GilbrideFor more details about Java logging API usage, see [Java Logging Overview](
68*55e87721SMatt Gilbridehttps://docs.oracle.com/javase/8/docs/technotes/guides/logging/overview.html).
69*55e87721SMatt Gilbride
70*55e87721SMatt Gilbride## ALPN is not configured properly
71*55e87721SMatt Gilbride
72*55e87721SMatt GilbrideIf you see exceptions related to `ALPN is not configured properly`, such as:
73*55e87721SMatt Gilbride
74*55e87721SMatt Gilbride```
75*55e87721SMatt GilbrideCaused by: java.lang.IllegalArgumentException: ALPN is not configured properly. See https://github.com/grpc/grpc-java/blob/master/SECURITY.md#troubleshooting for more information.
76*55e87721SMatt Gilbride```
77*55e87721SMatt Gilbride
78*55e87721SMatt GilbridePlease 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:
79*55e87721SMatt Gilbride- You are not on a [supported platform](https://github.com/googleapis/google-cloud-java/#supported-platforms).
80*55e87721SMatt Gilbride- There are classpath conflicts with `netty`.
81*55e87721SMatt Gilbride- Or, you are seeing any of the conflicts specified in [gRPC Troubleshooting guide](https://github.com/grpc/grpc-java/blob/master/SECURITY.md#troubleshooting).
82*55e87721SMatt Gilbride
83*55e87721SMatt Gilbride## ClassNotFoundException, NoSuchMethodError, NoClassDefFoundError
84*55e87721SMatt Gilbride
85*55e87721SMatt GilbrideThese errors are usually caused by having multiple versions or conflicting versions of the same dependency in the classpath.
86*55e87721SMatt GilbrideUsually these dependency conflicts occur with `guava` or `protobuf-java`.
87*55e87721SMatt Gilbride
88*55e87721SMatt GilbrideThere may be multiple sources for classpath conflicts:
89*55e87721SMatt Gilbride- Multiple versions of the same transitive dependency in the dependency tree
90*55e87721SMatt Gilbride- Your runtime classpath has different versions of dependencies than what you specified in the build
91*55e87721SMatt Gilbride
92*55e87721SMatt GilbrideFor example, if you have a direct or a transitive dependency on Guava version 19.0,
93*55e87721SMatt Gilbrideand `google-cloud-java` uses Guava version 30.0,
94*55e87721SMatt Gilbridethen `google-cloud-java` could be using Guava methods that don't exist in Guava 19.0,
95*55e87721SMatt Gilbrideand cause `NoSuchMethodError`.
96*55e87721SMatt Gilbride
97*55e87721SMatt GilbrideSimilarily, if your classpath has an older version of `protobuf-java`,
98*55e87721SMatt Gilbridebut `google-cloud-java` requires a newer version,
99*55e87721SMatt Gilbride then you might see `NoClassDefFoundError` that fails to initialize `google-cloud-java` classes. For example:
100*55e87721SMatt Gilbride
101*55e87721SMatt Gilbride```
102*55e87721SMatt Gilbridejava.lang.NoClassDefFoundError: Could not initialize class com.google.pubsub.v1.PubsubMessage$AttributesDefaultEntryHolder
103*55e87721SMatt Gilbride```
104*55e87721SMatt Gilbride
105*55e87721SMatt Gilbride### Validate the conflict
106*55e87721SMatt Gilbride
107*55e87721SMatt GilbrideCheck the dependency tree to see if you have multiple versions of the same dependencies:
108*55e87721SMatt Gilbride
109*55e87721SMatt Gilbride```
110*55e87721SMatt Gilbride$ mvn dependency:tree
111*55e87721SMatt Gilbride```
112*55e87721SMatt Gilbride
113*55e87721SMatt GilbrideLook for versions of potentially conflicting dependencies like `guava`, `protobuf-java`, etc.
114*55e87721SMatt Gilbride
115*55e87721SMatt GilbrideIf you experience the error only during runtime, then your runtime environment
116*55e87721SMatt Gilbridemight  be introducing conflicting JARs into your runtime classpath. A typical case
117*55e87721SMatt Gilbrideis that Hadoop, Spark, or other server software that your application runs on
118*55e87721SMatt Gilbridehas conflicting versions `netty`, `guava`, or `protobuf-java` JARs in the classpath.
119*55e87721SMatt Gilbride
120*55e87721SMatt Gilbride### Detecting conflicts during build
121*55e87721SMatt Gilbride
122*55e87721SMatt GilbrideTo detect dependency linkage errors at compile time, add the
123*55e87721SMatt Gilbride[Linkage Checker Enforcer Rule](https://github.com/GoogleCloudPlatform/cloud-opensource-java/tree/master/enforcer-rules)
124*55e87721SMatt Gilbridein your pom.xml:
125*55e87721SMatt Gilbride
126*55e87721SMatt Gilbride```
127*55e87721SMatt Gilbride      <plugin>
128*55e87721SMatt Gilbride        <groupId>org.apache.maven.plugins</groupId>
129*55e87721SMatt Gilbride        <artifactId>maven-enforcer-plugin</artifactId>
130*55e87721SMatt Gilbride        <version>3.0.0-M3</version>
131*55e87721SMatt Gilbride        <dependencies>
132*55e87721SMatt Gilbride          <dependency>
133*55e87721SMatt Gilbride            <groupId>com.google.cloud.tools</groupId>
134*55e87721SMatt Gilbride            <artifactId>linkage-checker-enforcer-rules</artifactId>
135*55e87721SMatt Gilbride            <version>1.5.7</version>
136*55e87721SMatt Gilbride          </dependency>
137*55e87721SMatt Gilbride        </dependencies>
138*55e87721SMatt Gilbride        <executions>
139*55e87721SMatt Gilbride          <execution>
140*55e87721SMatt Gilbride            <id>enforce-linkage-checker</id>
141*55e87721SMatt Gilbride            <!-- Important! Should run after compile -->
142*55e87721SMatt Gilbride            <phase>verify</phase>
143*55e87721SMatt Gilbride            <goals>
144*55e87721SMatt Gilbride              <goal>enforce</goal>
145*55e87721SMatt Gilbride            </goals>
146*55e87721SMatt Gilbride            <configuration>
147*55e87721SMatt Gilbride              <rules>
148*55e87721SMatt Gilbride                <LinkageCheckerRule
149*55e87721SMatt Gilbride                    implementation="com.google.cloud.tools.dependencies.enforcer.LinkageCheckerRule"/>
150*55e87721SMatt Gilbride              </rules>
151*55e87721SMatt Gilbride            </configuration>
152*55e87721SMatt Gilbride          </execution>
153*55e87721SMatt Gilbride        </executions>
154*55e87721SMatt Gilbride      </plugin>
155*55e87721SMatt Gilbride```
156*55e87721SMatt Gilbride
157*55e87721SMatt GilbrideThere is no way to detect runtime classpath conflicts though. You need to be fully
158*55e87721SMatt Gilbrideaware of which JARs/classes are included in the runtime classpath
159*55e87721SMatt Gilbrideas every server environment is different.
160*55e87721SMatt Gilbride
161*55e87721SMatt Gilbride### Resolving the conflict
162*55e87721SMatt Gilbride
163*55e87721SMatt GilbrideThere are different strategies to resolve conflicts, but you must understand the root cause of the conflicts. For example:
164*55e87721SMatt Gilbride
165*55e87721SMatt Gilbride- If you have control over the dependency tree, upgrade
166*55e87721SMatt Gilbride  offending dependencies (for example, upgrading Guava version). This is the
167*55e87721SMatt Gilbride  least hackish approach, but it is a lot of work that can require multiple releases
168*55e87721SMatt Gilbride   of multiple libraries to sync everything up.
169*55e87721SMatt Gilbride- If you can't modify and push new versions of your dependencies, import
170*55e87721SMatt Gilbride  `com.google.cloud:libraries-bom:25.1.0` (or a more recent version) and use that to
171*55e87721SMatt Gilbride  select consistent dependency versions. This is the easiest route.
172*55e87721SMatt Gilbride  For example, this is how you can depend on consistent versions of Guava and
173*55e87721SMatt Gilbride  `com.google.cloud:google-cloud-storage` without explicitly setting the version of either one:
174*55e87721SMatt Gilbride
175*55e87721SMatt Gilbride```
176*55e87721SMatt Gilbride  ...
177*55e87721SMatt Gilbride  <dependencyManagement>
178*55e87721SMatt Gilbride    <dependencies>
179*55e87721SMatt Gilbride      <dependency>
180*55e87721SMatt Gilbride        <groupId>com.google.cloud</groupId>
181*55e87721SMatt Gilbride        <artifactId>libraries-bom</artifactId>
182*55e87721SMatt Gilbride        <version>25.1.0</version>
183*55e87721SMatt Gilbride        <type>pom</type>
184*55e87721SMatt Gilbride        <scope>import</scope>
185*55e87721SMatt Gilbride       </dependency>
186*55e87721SMatt Gilbride     </dependencies>
187*55e87721SMatt Gilbride  </dependencyManagement>
188*55e87721SMatt Gilbride  ...
189*55e87721SMatt Gilbride  <dependencies>
190*55e87721SMatt Gilbride    <dependency>
191*55e87721SMatt Gilbride      <groupId>com.google.cloud</groupId>
192*55e87721SMatt Gilbride      <artifactId>google-cloud-storage</artifactId>
193*55e87721SMatt Gilbride    </dependency>
194*55e87721SMatt Gilbride    <dependency>
195*55e87721SMatt Gilbride      <groupId>com.google.guava</groupId>
196*55e87721SMatt Gilbride      <artifactId>guava</artifactId>
197*55e87721SMatt Gilbride    </dependency>
198*55e87721SMatt Gilbride    ...
199*55e87721SMatt Gilbride  </dependencies>
200*55e87721SMatt Gilbride  ...
201*55e87721SMatt Gilbride```
202*55e87721SMatt Gilbride
203*55e87721SMatt Gilbride- If changing dependency versions causes other failures,
204*55e87721SMatt Gilbride  consider [shading dependencies](https://maven.apache.org/plugins/maven-shade-plugin/)
205*55e87721SMatt Gilbride  that conflict with `google-cloud-java`.
206*55e87721SMatt Gilbride
207*55e87721SMatt Gilbride  For example, to shade `guava` and `protobuf-java`:
208*55e87721SMatt Gilbride
209*55e87721SMatt Gilbride```
210*55e87721SMatt Gilbride  <plugin>
211*55e87721SMatt Gilbride    <groupId>org.apache.maven.plugins</groupId>
212*55e87721SMatt Gilbride    <artifactId>maven-shade-plugin</artifactId>
213*55e87721SMatt Gilbride    <version>...</version>
214*55e87721SMatt Gilbride    <executions>
215*55e87721SMatt Gilbride      <execution>
216*55e87721SMatt Gilbride        <phase>package</phase>
217*55e87721SMatt Gilbride        <goals>
218*55e87721SMatt Gilbride          <goal>shade</goal>
219*55e87721SMatt Gilbride        </goals>
220*55e87721SMatt Gilbride        <configuration>
221*55e87721SMatt Gilbride          <keepDependenciesWithProvidedScope>false</keepDependenciesWithProvidedScope>
222*55e87721SMatt Gilbride          <relocations>
223*55e87721SMatt Gilbride            <!-- move protobuf to a shaded package -->
224*55e87721SMatt Gilbride            <relocation>
225*55e87721SMatt Gilbride              <pattern>com.google.protobuf</pattern>
226*55e87721SMatt Gilbride              <shadedPattern>myapp.shaded.com.google.protobuf</shadedPattern>
227*55e87721SMatt Gilbride            </relocation>
228*55e87721SMatt Gilbride            <!-- move Guava to a shaded package -->
229*55e87721SMatt Gilbride            <relocation>
230*55e87721SMatt Gilbride              <pattern>com.google.common</pattern>
231*55e87721SMatt Gilbride              <shadedPattern>myapp.shaded.com.google.common</shadedPattern>
232*55e87721SMatt Gilbride            </relocation>
233*55e87721SMatt Gilbride          </relocations>
234*55e87721SMatt Gilbride        </configuration>
235*55e87721SMatt Gilbride      </execution>
236*55e87721SMatt Gilbride    </executions>
237*55e87721SMatt Gilbride  </plugin>
238*55e87721SMatt Gilbride```
239