I see inconsistent behavior of JVM for the following test case using the latest jdk8u branch:
import java.io.IOException;
import java.security.Permission;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Checks each method that accesses the file system does the right permission
* check when there is a security manager set.
*/
public class CheckPermissions {
static class Checks {
private List<Permission> permissionsChecked = new ArrayList<>();
private Set<String> propertiesChecked = new HashSet<>();
private List<String> readsChecked = new ArrayList<>();
private List<String> writesChecked = new ArrayList<>();
private List<String> deletesChecked = new ArrayList<>();
private List<String> execsChecked = new ArrayList<>();
List<Permission> permissionsChecked() {
return permissionsChecked;
}
Set<String> propertiesChecked() {
return propertiesChecked;
}
List<String> readsChecked() {
return readsChecked;
}
List<String> writesChecked() {
return writesChecked;
}
List<String> deletesChecked() {
return deletesChecked;
}
List<String> execsChecked() {
return execsChecked;
}
}
static ThreadLocal<Checks> myChecks = new ThreadLocal<Checks>() {
@Override
protected Checks initialValue() {
return null;
}
};
static void prepare() {
myChecks.set(new Checks());
}
static class LoggingSecurityManager extends SecurityManager {
static void install() {
System.setSecurityManager(new LoggingSecurityManager());
}
@Override
public void checkPermission(Permission perm) {
Checks checks = myChecks.get();
if (checks != null)
checks.permissionsChecked().add(perm);
}
@Override
public void checkPropertyAccess(String key) {
Checks checks = myChecks.get();
if (checks != null)
checks.propertiesChecked().add(key);
}
@Override
public void checkRead(String file) {
Checks checks = myChecks.get();
if (checks != null)
checks.readsChecked().add(file);
}
@Override
public void checkWrite(String file) {
Checks checks = myChecks.get();
if (checks != null)
checks.writesChecked().add(file);
}
@Override
public void checkDelete(String file) {
Checks checks = myChecks.get();
if (checks != null)
checks.deletesChecked().add(file);
}
@Override
public void checkExec(String file) {
Checks checks = myChecks.get();
if (checks != null)
checks.execsChecked().add(file);
}
}
public static void main(String[] args) throws IOException {
LoggingSecurityManager.install();
prepare();
}
}
It executes fine with the following options:
$java -Xcomp CheckPermissions
$java CheckPermissions
But it fails to execute under C2 compile only mode:
$java -Xcomp -XX:-TieredCompilation CheckPermissions
Exception in thread "main" java.lang.LinkageError: CheckPermissions$Checks
at CheckPermissions.prepare(CheckPermissions.java:56)
at CheckPermissions.main(CheckPermissions.java:109)
import java.io.IOException;
import java.security.Permission;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Checks each method that accesses the file system does the right permission
* check when there is a security manager set.
*/
public class CheckPermissions {
static class Checks {
private List<Permission> permissionsChecked = new ArrayList<>();
private Set<String> propertiesChecked = new HashSet<>();
private List<String> readsChecked = new ArrayList<>();
private List<String> writesChecked = new ArrayList<>();
private List<String> deletesChecked = new ArrayList<>();
private List<String> execsChecked = new ArrayList<>();
List<Permission> permissionsChecked() {
return permissionsChecked;
}
Set<String> propertiesChecked() {
return propertiesChecked;
}
List<String> readsChecked() {
return readsChecked;
}
List<String> writesChecked() {
return writesChecked;
}
List<String> deletesChecked() {
return deletesChecked;
}
List<String> execsChecked() {
return execsChecked;
}
}
static ThreadLocal<Checks> myChecks = new ThreadLocal<Checks>() {
@Override
protected Checks initialValue() {
return null;
}
};
static void prepare() {
myChecks.set(new Checks());
}
static class LoggingSecurityManager extends SecurityManager {
static void install() {
System.setSecurityManager(new LoggingSecurityManager());
}
@Override
public void checkPermission(Permission perm) {
Checks checks = myChecks.get();
if (checks != null)
checks.permissionsChecked().add(perm);
}
@Override
public void checkPropertyAccess(String key) {
Checks checks = myChecks.get();
if (checks != null)
checks.propertiesChecked().add(key);
}
@Override
public void checkRead(String file) {
Checks checks = myChecks.get();
if (checks != null)
checks.readsChecked().add(file);
}
@Override
public void checkWrite(String file) {
Checks checks = myChecks.get();
if (checks != null)
checks.writesChecked().add(file);
}
@Override
public void checkDelete(String file) {
Checks checks = myChecks.get();
if (checks != null)
checks.deletesChecked().add(file);
}
@Override
public void checkExec(String file) {
Checks checks = myChecks.get();
if (checks != null)
checks.execsChecked().add(file);
}
}
public static void main(String[] args) throws IOException {
LoggingSecurityManager.install();
prepare();
}
}
It executes fine with the following options:
$java -Xcomp CheckPermissions
$java CheckPermissions
But it fails to execute under C2 compile only mode:
$java -Xcomp -XX:-TieredCompilation CheckPermissions
Exception in thread "main" java.lang.LinkageError: CheckPermissions$Checks
at CheckPermissions.prepare(CheckPermissions.java:56)
at CheckPermissions.main(CheckPermissions.java:109)