Skip to content

Commit a94f859

Browse files
committed
[GR-55282] Cleanup logging code in Espresso
PullRequest: graal/18282
2 parents 3cec7d0 + b6b2430 commit a94f859

File tree

3 files changed

+29
-202
lines changed
  • espresso/src
    • com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl
    • com.oracle.truffle.espresso.libjavavm/src/com/oracle/truffle/espresso/libjavavm/arghelper
  • sdk/src/org.graalvm.launcher/src/org/graalvm/launcher

3 files changed

+29
-202
lines changed

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2730,6 +2730,7 @@ static CommandResult createReply(Packet packet, JDWPContext context) {
27302730
writeValue(sigbyte, value, reply, true, context);
27312731
}
27322732
} catch (ArrayIndexOutOfBoundsException | InteropException ex) {
2733+
ex.printStackTrace();
27332734
// invalid slot provided
27342735
reply.errorCode(ErrorCodes.INVALID_SLOT);
27352736
return new CommandResult(reply);

espresso/src/com.oracle.truffle.espresso.libjavavm/src/com/oracle/truffle/espresso/libjavavm/arghelper/PolyglotArgs.java

Lines changed: 20 additions & 197 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -26,20 +26,8 @@
2626
import static com.oracle.truffle.espresso.libjavavm.Arguments.abort;
2727
import static com.oracle.truffle.espresso.libjavavm.Arguments.abortExperimental;
2828
import static com.oracle.truffle.espresso.libjavavm.arghelper.ArgumentsHandler.isBooleanOption;
29-
import static java.nio.file.StandardOpenOption.APPEND;
30-
import static java.nio.file.StandardOpenOption.CREATE;
31-
import static java.nio.file.StandardOpenOption.CREATE_NEW;
32-
import static java.nio.file.StandardOpenOption.WRITE;
3329

34-
import java.io.BufferedOutputStream;
3530
import java.io.IOException;
36-
import java.io.OutputStream;
37-
import java.nio.channels.FileChannel;
38-
import java.nio.channels.OverlappingFileLockException;
39-
import java.nio.file.FileAlreadyExistsException;
40-
import java.nio.file.Files;
41-
import java.nio.file.LinkOption;
42-
import java.nio.file.NoSuchFileException;
4331
import java.nio.file.Path;
4432
import java.nio.file.Paths;
4533
import java.util.ArrayList;
@@ -50,7 +38,7 @@
5038
import java.util.Map;
5139
import java.util.logging.Level;
5240

53-
import org.graalvm.collections.Pair;
41+
import org.graalvm.launcher.Launcher;
5442
import org.graalvm.options.OptionCategory;
5543
import org.graalvm.options.OptionDescriptor;
5644
import org.graalvm.options.OptionDescriptors;
@@ -90,7 +78,7 @@ void argumentProcessingDone() {
9078
}
9179
if (logFile != null) {
9280
try {
93-
builder.logHandler(newLogStream(logFile));
81+
builder.logHandler(Launcher.newLogStream(logFile));
9482
} catch (IOException ioe) {
9583
throw abort(ioe.toString());
9684
}
@@ -161,18 +149,15 @@ void parsePolyglotOption(String group, String key, String value, String arg, boo
161149

162150
private OptionDescriptor findOptionDescriptor(String group, String key) {
163151
OptionDescriptors descriptors = null;
164-
switch (group) {
165-
case "engine":
166-
descriptors = getTempEngine().getOptions();
167-
break;
168-
default:
169-
Engine engine = getTempEngine();
170-
if (engine.getLanguages().containsKey(group)) {
171-
descriptors = engine.getLanguages().get(group).getOptions();
172-
} else if (engine.getInstruments().containsKey(group)) {
173-
descriptors = engine.getInstruments().get(group).getOptions();
174-
}
175-
break;
152+
if (group.equals("engine")) {
153+
descriptors = getTempEngine().getOptions();
154+
} else {
155+
Engine engine = getTempEngine();
156+
if (engine.getLanguages().containsKey(group)) {
157+
descriptors = engine.getLanguages().get(group).getOptions();
158+
} else if (engine.getInstruments().containsKey(group)) {
159+
descriptors = engine.getInstruments().get(group).getOptions();
160+
}
176161
}
177162
if (descriptors == null) {
178163
return null;
@@ -231,7 +216,7 @@ static final class PrintableOption implements Comparable<PrintableOption> {
231216
final String option;
232217
final String description;
233218

234-
protected PrintableOption(String option, String description) {
219+
private PrintableOption(String option, String description) {
235220
this.option = option;
236221
this.description = description;
237222
}
@@ -243,21 +228,12 @@ public int compareTo(PrintableOption o) {
243228
}
244229

245230
private static String optionsTitle(String kind, OptionCategory optionCategory) {
246-
String category;
247-
switch (optionCategory) {
248-
case USER:
249-
category = "User ";
250-
break;
251-
case EXPERT:
252-
category = "Expert ";
253-
break;
254-
case INTERNAL:
255-
category = "Internal ";
256-
break;
257-
default:
258-
category = "";
259-
break;
260-
}
231+
String category = switch (optionCategory) {
232+
case USER -> "User ";
233+
case EXPERT -> "Expert ";
234+
case INTERNAL -> "Internal ";
235+
default -> "";
236+
};
261237
return category + kind + " options:";
262238
}
263239

@@ -291,9 +267,7 @@ private static PrintableOption asPrintableOption(OptionDescriptor descriptor) {
291267
StringBuilder key = new StringBuilder("--");
292268
key.append(descriptor.getName());
293269
Object defaultValue = descriptor.getKey().getDefaultValue();
294-
if (defaultValue instanceof Boolean && defaultValue == Boolean.FALSE) {
295-
// nothing to print
296-
} else {
270+
if (defaultValue != Boolean.FALSE) {
297271
key.append("=<");
298272
key.append(descriptor.getKey().getType().getName());
299273
key.append(">");
@@ -320,155 +294,4 @@ private static List<Instrument> sortedInstruments(Engine engine) {
320294
return instruments;
321295
}
322296

323-
/**
324-
* Creates a new log file. The method uses a supplemental lock file to determine the file is
325-
* still opened for output; in that case, it creates a different file, named `path'1, `path`2,
326-
* ... until it finds a free name. Files not locked (actively written to) are overwritten.
327-
*
328-
* @param path the desired output for log
329-
* @return the OutputStream for logging
330-
* @throws IOException in case of I/O error opening the file
331-
* @since 20.0
332-
*/
333-
protected static OutputStream newLogStream(Path path) throws IOException {
334-
Path usedPath = path;
335-
Path fileNamePath = path.getFileName();
336-
String fileName = fileNamePath == null ? "" : fileNamePath.toString();
337-
Path lockFile = null;
338-
FileChannel lockFileChannel = null;
339-
for (int unique = 0;; unique++) {
340-
StringBuilder lockFileNameBuilder = new StringBuilder(fileName);
341-
if (unique > 0) {
342-
lockFileNameBuilder.append(unique);
343-
usedPath = path.resolveSibling(lockFileNameBuilder.toString());
344-
}
345-
lockFileNameBuilder.append(".lck");
346-
lockFile = path.resolveSibling(lockFileNameBuilder.toString());
347-
Pair<FileChannel, Boolean> openResult = openChannel(lockFile);
348-
if (openResult != null) {
349-
lockFileChannel = openResult.getLeft();
350-
if (lock(lockFileChannel, openResult.getRight())) {
351-
break;
352-
} else {
353-
// Close and try next name
354-
lockFileChannel.close();
355-
}
356-
}
357-
}
358-
assert lockFile != null && lockFileChannel != null;
359-
boolean success = false;
360-
try {
361-
OutputStream stream = new LockableOutputStream(
362-
new BufferedOutputStream(Files.newOutputStream(usedPath, WRITE, CREATE, APPEND)),
363-
lockFile,
364-
lockFileChannel);
365-
success = true;
366-
return stream;
367-
} finally {
368-
if (!success) {
369-
LockableOutputStream.unlock(lockFile, lockFileChannel);
370-
}
371-
}
372-
}
373-
374-
private static Pair<FileChannel, Boolean> openChannel(Path path) throws IOException {
375-
FileChannel channel = null;
376-
for (int retries = 0; channel == null && retries < 2; retries++) {
377-
try {
378-
channel = FileChannel.open(path, CREATE_NEW, WRITE);
379-
return Pair.create(channel, true);
380-
} catch (FileAlreadyExistsException faee) {
381-
// Maybe a FS race showing a zombie file, try to reuse it
382-
if (Files.isRegularFile(path, LinkOption.NOFOLLOW_LINKS) && isParentWritable(path)) {
383-
try {
384-
channel = FileChannel.open(path, WRITE, APPEND);
385-
return Pair.create(channel, false);
386-
} catch (NoSuchFileException x) {
387-
// FS Race, next try we should be able to create with CREATE_NEW
388-
} catch (IOException x) {
389-
return null;
390-
}
391-
} else {
392-
return null;
393-
}
394-
}
395-
}
396-
return null;
397-
}
398-
399-
private static boolean isParentWritable(Path path) {
400-
Path parentPath = path.getParent();
401-
if (parentPath == null && !path.isAbsolute()) {
402-
parentPath = path.toAbsolutePath().getParent();
403-
}
404-
return parentPath != null && Files.isWritable(parentPath);
405-
}
406-
407-
private static boolean lock(FileChannel lockFileChannel, boolean newFile) {
408-
boolean available = false;
409-
try {
410-
available = lockFileChannel.tryLock() != null;
411-
} catch (OverlappingFileLockException ofle) {
412-
// VM already holds lock continue with available set to false
413-
} catch (IOException ioe) {
414-
// Locking not supported by OS
415-
available = newFile;
416-
}
417-
return available;
418-
}
419-
420-
private static final class LockableOutputStream extends OutputStream {
421-
422-
private final OutputStream delegate;
423-
private final Path lockFile;
424-
private final FileChannel lockFileChannel;
425-
426-
LockableOutputStream(OutputStream delegate, Path lockFile, FileChannel lockFileChannel) {
427-
this.delegate = delegate;
428-
this.lockFile = lockFile;
429-
this.lockFileChannel = lockFileChannel;
430-
}
431-
432-
@Override
433-
public void write(int b) throws IOException {
434-
delegate.write(b);
435-
}
436-
437-
@Override
438-
public void write(byte[] b) throws IOException {
439-
delegate.write(b);
440-
}
441-
442-
@Override
443-
public void write(byte[] b, int off, int len) throws IOException {
444-
delegate.write(b, off, len);
445-
}
446-
447-
@Override
448-
public void flush() throws IOException {
449-
delegate.flush();
450-
}
451-
452-
@Override
453-
public void close() throws IOException {
454-
try {
455-
delegate.close();
456-
} finally {
457-
unlock(lockFile, lockFileChannel);
458-
}
459-
}
460-
461-
private static void unlock(Path lockFile, FileChannel lockFileChannel) {
462-
try {
463-
lockFileChannel.close();
464-
} catch (IOException ioe) {
465-
// Error while closing the channel, ignore.
466-
}
467-
try {
468-
Files.delete(lockFile);
469-
} catch (IOException ioe) {
470-
// Error while deleting the lock file, ignore.
471-
}
472-
}
473-
}
474297
}

sdk/src/org.graalvm.launcher/src/org/graalvm/launcher/Launcher.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -1704,8 +1704,12 @@ private static String quote(String str) {
17041704
* @throws IOException in case of I/O error opening the file
17051705
* @since 20.0
17061706
*/
1707-
protected static OutputStream newLogStream(Path path) throws IOException {
1707+
public static OutputStream newLogStream(Path path) throws IOException {
17081708
Path usedPath = path;
1709+
Path parent = path.getParent();
1710+
if (parent != null) {
1711+
Files.createDirectories(parent);
1712+
}
17091713
Path fileNamePath = path.getFileName();
17101714
String fileName = fileNamePath == null ? "" : fileNamePath.toString();
17111715
OutputStream outputStream;
@@ -1734,7 +1738,6 @@ protected static OutputStream newLogStream(Path path) throws IOException {
17341738
}
17351739
}
17361740
}
1737-
assert lockFile != null && lockFileChannel != null;
17381741
boolean success = false;
17391742
try {
17401743
outputStream = new LockableOutputStream(
@@ -1752,8 +1755,8 @@ protected static OutputStream newLogStream(Path path) throws IOException {
17521755
}
17531756

17541757
private static Pair<FileChannel, Boolean> openChannel(Path path) throws IOException {
1755-
FileChannel channel = null;
1756-
for (int retries = 0; channel == null && retries < 2; retries++) {
1758+
FileChannel channel;
1759+
for (int retries = 0; retries < 2; retries++) {
17571760
try {
17581761
channel = FileChannel.open(path, CREATE_NEW, WRITE);
17591762
return Pair.create(channel, true);

0 commit comments

Comments
 (0)