Skip to content

Commit

Permalink
7016187: javac -h could generate conflict .h for inner class and cl…
Browse files Browse the repository at this point in the history
…ass name with '_'

Reviewed-by: vromero
  • Loading branch information
archiecobbs authored and Vicente Romero committed Mar 18, 2023
1 parent 033c0b1 commit e339e18
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import javax.tools.FileObject;
Expand Down Expand Up @@ -84,6 +85,12 @@ public class JNIWriter {
*/
private boolean checkAll;

/**
* Mapping from output file name to class name, for all classes we've written.
* This is used to detect when two classes generate the same output file.
*/
private final HashMap<String, String> filesWritten = new HashMap<>();

/**
* If true, class files will be written in module-specific subdirectories
* of the NATIVE_HEADER_OUTPUT location.
Expand Down Expand Up @@ -183,9 +190,14 @@ public FileObject write(ClassSymbol c) throws IOException {
} else {
outLocn = StandardLocation.NATIVE_HEADER_OUTPUT;
}
FileObject outFile
= fileManager.getFileForOutput(outLocn,
"", className.replaceAll("[.$]", "_") + ".h", null);
String fileName = className.replaceAll("[.$]", "_") + ".h";
String prevName = filesWritten.put(fileName, className);
if (prevName != null) {
throw new IOException(String.format(
"native header file collision between %s and %s (both generate %s)",
prevName, className, fileName));
}
FileObject outFile = fileManager.getFileForOutput(outLocn, "", fileName, null);
PrintWriter out = new PrintWriter(outFile.openWriter());
try {
write(out, c);
Expand Down
28 changes: 27 additions & 1 deletion test/langtools/tools/javac/nativeHeaders/NativeHeaderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

/*
* @test
* @bug 7150368 8003412 8000407
* @bug 7150368 8003412 8000407 7016187
* @summary javac should include basic ability to generate native headers
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.file
Expand Down Expand Up @@ -149,6 +149,32 @@ void annoNestedClassTest(RunKind rk, GenKind gk) throws Exception {
test(rk, gk, files, expect);
}

@Test
void conflictTest(RunKind rk, GenKind gk) throws Exception {

// These two classes will generate the same header file "Foo_Bar.h"
List<File> files = new ArrayList<File>();
files.add(createFile("p/Foo.java", """
public class Foo {
public static class Bar {
public static native void method1();
}
}
"""));
files.add(createFile("p/Foo_Bar.java", """
public class Foo_Bar {
public static native void method2();
}
"""));

try {
test(rk, gk, files, null);
throw new AssertionError("expected failure");
} catch (Exception e) {
// expected
}
}

/**
* The worker method for each test case.
* Compile the files and verify that exactly the expected set of header files
Expand Down

1 comment on commit e339e18

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.