Skip to content

Commit a236fca

Browse files
DavideDhferentschik
authored andcommitted
HV-1017 Avoid checking the TCCL for JavaFX
1 parent 2e99551 commit a236fca

File tree

4 files changed

+123
-28
lines changed

4 files changed

+123
-28
lines changed

engine-jdk8-tests/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,10 @@
8080
<artifactId>fest-assert</artifactId>
8181
<scope>test</scope>
8282
</dependency>
83+
<dependency>
84+
<groupId>org.jboss.shrinkwrap</groupId>
85+
<artifactId>shrinkwrap-impl-base</artifactId>
86+
<scope>test</scope>
87+
</dependency>
8388
</dependencies>
8489
</project>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Hibernate Validator, declare and validate application constraints
3+
*
4+
* License: Apache License, Version 2.0
5+
* See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
6+
*/
7+
package org.hibernate.validator.test.internal.engine.valuehandling;
8+
9+
import java.security.AccessController;
10+
import java.security.PrivilegedAction;
11+
12+
import javax.validation.ValidationException;
13+
14+
import org.fest.assertions.Assertions;
15+
import org.hibernate.validator.internal.util.privilegedactions.LoadClass;
16+
import org.hibernate.validator.testutil.TestForIssue;
17+
18+
import org.jboss.shrinkwrap.api.ShrinkWrap;
19+
import org.jboss.shrinkwrap.api.classloader.ShrinkWrapClassLoader;
20+
import org.jboss.shrinkwrap.api.spec.JavaArchive;
21+
import org.junit.Test;
22+
23+
/**
24+
* @author Davide D'Alto
25+
*/
26+
@TestForIssue( jiraKey = "HV-1017")
27+
public class JavaFXClassLoadingTest {
28+
29+
/**
30+
* This class will be present in the TCCL because is part of JDK 8
31+
*/
32+
private static final String JAVAFX_APPLICATION_CLASS = "javafx.application.Application";
33+
34+
@Test
35+
public void shouldBeAbleToFindTheClassInTCCL() throws Exception {
36+
JavaArchive archive = ShrinkWrap.create( JavaArchive.class ).addClass( JavaFXClassLoadingTest.class );
37+
ShrinkWrapClassLoader classLoaderWithoutExpectedClass = new ShrinkWrapClassLoader( (ClassLoader) null, archive );
38+
Assertions.assertThat( isClassPresent( JAVAFX_APPLICATION_CLASS, classLoaderWithoutExpectedClass, true ) ).isTrue();
39+
}
40+
41+
@Test
42+
public void shouldNotFindTheClass() throws Exception {
43+
JavaArchive archive = ShrinkWrap.create( JavaArchive.class ).addClass( JavaFXClassLoadingTest.class );
44+
ShrinkWrapClassLoader classLoaderWithoutExpectedClass = new ShrinkWrapClassLoader( (ClassLoader) null, archive );
45+
Assertions.assertThat( isClassPresent( JAVAFX_APPLICATION_CLASS, classLoaderWithoutExpectedClass, false ) ).isFalse();
46+
}
47+
48+
private static boolean isClassPresent(String className, ClassLoader classLoader, boolean fallbackOnTCCL) {
49+
try {
50+
run( LoadClass.action( className, classLoader, fallbackOnTCCL ) );
51+
return true;
52+
}
53+
catch (ValidationException e) {
54+
return false;
55+
}
56+
}
57+
58+
/**
59+
* Runs the given privileged action, using a privileged block if required.
60+
* <p>
61+
* <b>NOTE:</b> This must never be changed into a publicly available method to avoid execution of arbitrary
62+
* privileged actions within HV's protection domain.
63+
*/
64+
private static <T> T run(PrivilegedAction<T> action) {
65+
return System.getSecurityManager() != null ? AccessController.doPrivileged( action ) : action.run();
66+
}
67+
}

engine/src/main/java/org/hibernate/validator/internal/engine/ConfigurationImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -495,12 +495,12 @@ private void applyXmlSettings(ValidationBootstrapParameters xmlParameters) {
495495
}
496496

497497
private boolean isJavaFxInClasspath() {
498-
return isClassPresent( "javafx.application.Application" );
498+
return isClassPresent( "javafx.application.Application", false );
499499
}
500500

501-
private boolean isClassPresent(String className) {
501+
private boolean isClassPresent(String className, boolean fallbackOnTCCL) {
502502
try {
503-
run( LoadClass.action( className, getClass().getClassLoader() ) );
503+
run( LoadClass.action( className, getClass().getClassLoader(), fallbackOnTCCL ) );
504504
return true;
505505
}
506506
catch ( ValidationException e ) {

engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/LoadClass.java

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,23 @@ public final class LoadClass implements PrivilegedAction<Class<?>> {
3636

3737
private final ClassLoader classLoader;
3838

39+
/**
40+
* when true, it will check the Thread Context ClassLoader when the class is not found in the provided one
41+
*/
42+
private final boolean fallbackOnTCCL;
43+
3944
public static LoadClass action(String className, ClassLoader classLoader) {
40-
return new LoadClass( className, classLoader );
45+
return new LoadClass( className, classLoader, true );
46+
}
47+
48+
public static LoadClass action(String className, ClassLoader classLoader, boolean fallbackOnTCCL) {
49+
return new LoadClass( className, classLoader, fallbackOnTCCL );
4150
}
4251

43-
private LoadClass(String className, ClassLoader classLoader) {
52+
private LoadClass(String className, ClassLoader classLoader, boolean fallbackOnTCCL) {
4453
this.className = className;
4554
this.classLoader = classLoader;
55+
this.fallbackOnTCCL = fallbackOnTCCL;
4656
}
4757

4858
@Override
@@ -67,49 +77,62 @@ private Class<?> loadClassInValidatorNameSpace() {
6777
catch ( RuntimeException e ) {
6878
// ignore
6979
}
70-
try {
71-
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
72-
if ( contextClassLoader != null ) {
73-
return Class.forName( className, false, contextClassLoader );
80+
if ( fallbackOnTCCL ) {
81+
try {
82+
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
83+
if ( contextClassLoader != null ) {
84+
return Class.forName( className, false, contextClassLoader );
85+
}
86+
else {
87+
throw log.getUnableToLoadClassException( className );
88+
}
7489
}
75-
else {
76-
throw log.getUnableToLoadClassException( className );
90+
catch ( ClassNotFoundException e ) {
91+
throw log.getUnableToLoadClassException( className, e );
7792
}
7893
}
79-
catch ( ClassNotFoundException e ) {
80-
throw log.getUnableToLoadClassException( className, e );
94+
else {
95+
throw log.getUnableToLoadClassException( className );
8196
}
8297
}
8398

8499
private Class<?> loadNonValidatorClass() {
100+
Exception exception = null;
85101
try {
86102
if ( classLoader != null ) {
87103
return Class.forName( className, false, classLoader );
88104
}
89105
}
90106
catch ( ClassNotFoundException e ) {
91107
// ignore - try using the classloader of the caller first
108+
exception = e;
92109
}
93110
catch ( RuntimeException e ) {
94111
// ignore
112+
exception = e;
95113
}
96-
try {
97-
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
98-
if ( contextClassLoader != null ) {
99-
return Class.forName( className, false, contextClassLoader );
114+
if ( fallbackOnTCCL ) {
115+
try {
116+
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
117+
if ( contextClassLoader != null ) {
118+
return Class.forName( className, false, contextClassLoader );
119+
}
120+
}
121+
catch ( ClassNotFoundException e ) {
122+
// ignore - try using the classloader of the caller first
123+
}
124+
catch ( RuntimeException e ) {
125+
// ignore
126+
}
127+
try {
128+
return Class.forName( className, true, LoadClass.class.getClassLoader() );
129+
}
130+
catch ( ClassNotFoundException e ) {
131+
throw log.getUnableToLoadClassException( className, e );
100132
}
101133
}
102-
catch ( ClassNotFoundException e ) {
103-
// ignore - try using the classloader of the caller first
104-
}
105-
catch ( RuntimeException e ) {
106-
// ignore
107-
}
108-
try {
109-
return Class.forName( className, true, LoadClass.class.getClassLoader() );
110-
}
111-
catch ( ClassNotFoundException e ) {
112-
throw log.getUnableToLoadClassException( className, e );
134+
else {
135+
throw log.getUnableToLoadClassException( className, exception );
113136
}
114137
}
115138
}

0 commit comments

Comments
 (0)