Repository navigation
Working guava - #16237
Working guava#16237AbhishekKumar9984 wants to merge 7 commits into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Code Review
This pull request refactors the codebase to migrate away from deprecated or removed Guava APIs, replacing 'Closeables.closeQuietly' with manual try-catch blocks, updating 'Service' lifecycle methods to use asynchronous start/stop patterns, and replacing 'Objects.firstNonNull' with 'MoreObjects.firstNonNull'. Feedback on these changes highlights several critical issues: potential 'NullPointerException's where null-safety was lost during the 'closeQuietly' replacements, potential 'IllegalStateException's from starting already-running shared services, and minor inefficiencies such as reading entire files into memory in tests or using 'Optional' in frequently called methods.
| try { | ||
|
|
||
| sshSession.close(); | ||
|
|
||
| } catch (Exception ignored) { | ||
|
|
||
| } |
There was a problem hiding this comment.
| try { | ||
|
|
||
| sshSession.close(); | ||
|
|
||
| } catch (Exception ignored) { | ||
|
|
||
| } |
There was a problem hiding this comment.
| try { | ||
|
|
||
| input.close(); | ||
|
|
||
| } catch (Exception ignored) { | ||
|
|
||
| } |
There was a problem hiding this comment.
| String line; | ||
| try (InputStreamReader reader = new InputStreamReader(Locations.newInputSupplier(resultLocation).getInput(), | ||
| Charsets.UTF_8)) { | ||
| line = CharStreams.readLines(reader).stream().findFirst().orElse(null); | ||
| } |
There was a problem hiding this comment.
Using CharStreams.readLines(reader) reads the entire file into memory just to retrieve the first line, which is highly inefficient and can cause OutOfMemoryError for larger files. We should use a BufferedReader to read only the first line.
| String line; | |
| try (InputStreamReader reader = new InputStreamReader(Locations.newInputSupplier(resultLocation).getInput(), | |
| Charsets.UTF_8)) { | |
| line = CharStreams.readLines(reader).stream().findFirst().orElse(null); | |
| } | |
| String line; | |
| try (java.io.BufferedReader reader = new java.io.BufferedReader( | |
| new InputStreamReader(Locations.newInputSupplier(resultLocation).getInput(), Charsets.UTF_8))) { | |
| line = reader.readLine(); | |
| } |
| taskContextProvider = Optional.ofNullable(taskContextProvider) | ||
| .orElseGet(taskContextProviderSupplier::get); |
There was a problem hiding this comment.
Using Optional.ofNullable(...).orElseGet(...) creates a new Optional object on every invocation of getTaskContextProvider(). Since this method can be called frequently, we should use a standard null check to avoid unnecessary object allocations.
if (taskContextProvider == null) {
taskContextProvider = taskContextProviderSupplier.get();
}| if (messagingService instanceof Service) { | ||
| ((Service) messagingService).startAndWait(); | ||
| ((Service) messagingService).startAsync().awaitRunning(); | ||
| } |
There was a problem hiding this comment.
Since messagingService is a shared global service, calling startAsync() directly when it is already running will throw an IllegalStateException. We should check if the service state is NEW before starting it.
| if (messagingService instanceof Service) { | |
| ((Service) messagingService).startAndWait(); | |
| ((Service) messagingService).startAsync().awaitRunning(); | |
| } | |
| if (messagingService instanceof Service) { | |
| Service service = (Service) messagingService; | |
| if (service.state() == Service.State.NEW) { | |
| service.startAsync().awaitRunning(); | |
| } else { | |
| service.awaitRunning(); | |
| } | |
| } |
| applicationLifecycleService.startAsync(); | ||
| programRuntimeService.startAsync(); | ||
| metricsCollectionService.startAsync(); | ||
| programNotificationSubscriberService.startAsync(); | ||
| programStopSubscriberService.startAsync(); | ||
| applicationLifecycleService.awaitRunning(); | ||
| programRuntimeService.awaitRunning(); | ||
| metricsCollectionService.awaitRunning(); | ||
| programNotificationSubscriberService.awaitRunning(); | ||
| programStopSubscriberService.awaitRunning(); |
There was a problem hiding this comment.
Since metricsCollectionService is a shared global service, calling startAsync() directly when it is already running will throw an IllegalStateException. We should check if the service state is NEW before starting it.
| applicationLifecycleService.startAsync(); | |
| programRuntimeService.startAsync(); | |
| metricsCollectionService.startAsync(); | |
| programNotificationSubscriberService.startAsync(); | |
| programStopSubscriberService.startAsync(); | |
| applicationLifecycleService.awaitRunning(); | |
| programRuntimeService.awaitRunning(); | |
| metricsCollectionService.awaitRunning(); | |
| programNotificationSubscriberService.awaitRunning(); | |
| programStopSubscriberService.awaitRunning(); | |
| applicationLifecycleService.startAsync(); | |
| programRuntimeService.startAsync(); | |
| if (metricsCollectionService.state() == Service.State.NEW) { | |
| metricsCollectionService.startAsync(); | |
| } | |
| programNotificationSubscriberService.startAsync(); | |
| programStopSubscriberService.startAsync(); | |
| applicationLifecycleService.awaitRunning(); | |
| programRuntimeService.awaitRunning(); | |
| metricsCollectionService.awaitRunning(); | |
| programNotificationSubscriberService.awaitRunning(); | |
| programStopSubscriberService.awaitRunning(); |
| try { | ||
|
|
||
| pluginInstantiator.close(); | ||
|
|
||
| } catch (Exception ignored) { | ||
|
|
||
| } |
There was a problem hiding this comment.
If an exception is thrown before pluginInstantiator is initialized, it will be null in the catch block, and calling pluginInstantiator.close() will throw a NullPointerException. We should add an explicit null check.
if (pluginInstantiator != null) {
try {
pluginInstantiator.close();
} catch (Exception ignored) {
}
}| try { | ||
|
|
||
| pluginInstantiator.close(); | ||
|
|
||
| } catch (Exception ignored) { | ||
|
|
||
| } |
There was a problem hiding this comment.
If an exception is thrown before pluginInstantiator is initialized, it will be null in the catch block, and calling pluginInstantiator.close() will throw a NullPointerException. We should add an explicit null check.
if (pluginInstantiator != null) {
try {
pluginInstantiator.close();
} catch (Exception ignored) {
}
}| try (java.io.InputStream in = Resources.asByteSource(url).openStream(); | ||
| java.io.OutputStream out = new java.io.FileOutputStream(tempFile)) { | ||
| com.google.common.io.ByteStreams.copy(in, out); | ||
| } |
There was a problem hiding this comment.
Instead of manually creating a FileOutputStream and copying bytes using ByteStreams.copy, we can use java.nio.file.Files.copy which is more concise, efficient, and consistent with other copy operations in this file.
try (java.io.InputStream in = Resources.asByteSource(url).openStream()) {
java.nio.file.Files.copy(in, tempFile.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING);
}
No description provided.