Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Controller.shouldBeCheckedForEnhancement method #1272

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 26 additions & 27 deletions framework/src/play/mvc/Controller.java
Original file line number Diff line number Diff line change
Expand Up @@ -1215,52 +1215,51 @@ protected static <T> T await(Future<T> future) {
* leaving actionInvoke into the app, and before reentering Controller.await
*/
private static void verifyContinuationsEnhancement() {
// only check in dev mode..

if (Play.mode == Play.Mode.PROD) {
return;
}

try {
throw new Exception();

} catch (Exception e) {
boolean haveSeenFirstApplicationClass = false;
boolean verificationStarted = false;

for (StackTraceElement ste : e.getStackTrace()) {
String className = ste.getClassName();

if (!haveSeenFirstApplicationClass) {
haveSeenFirstApplicationClass = Play.classes.getApplicationClass(className) != null;
// when haveSeenFirstApplicationClass is set to true, we are
// entering the user application code..
if (!verificationStarted) {
// Look for first application class to mark start of verification
verificationStarted = Play.classes.getApplicationClass(className) != null;
}

if (haveSeenFirstApplicationClass) {
if (shouldBeCheckedForEnhancement(className)) {
// we're back into the play framework code...
return; // done checking
} else {
// is this class enhanced?
boolean enhanced = ContinuationEnhancer.isEnhanced(className);
if (!enhanced) {
throw new ContinuationsException(
"Cannot use await/continuations when not all application classes on the callstack are properly enhanced. The following class is not enhanced: "
+ className);
}
}
if(verificationStarted && shouldNotBeEnhanced(className)) {
// When we next see a class that should not be enhanced, the verification is complete
return;
}
}

if(verificationStarted) {
assertEnhancedClass(className);
}
}
}
}


/**
* Checks if the classname is from the jdk, sun or play package and therefore should not be checked for enhancement
* @param String className
* @return boolean
* Checks if the classname is from a play package or from the JDK. These classes should not be enhanced and
* should not be verified. These presence of these packages indicate the verification is complete.
*/
static boolean shouldBeCheckedForEnhancement(String className)
{
return className.startsWith("jdk.") || className.startsWith("sun.") || className.startsWith("play.");
static boolean shouldNotBeEnhanced(String className) {
return className.startsWith("play.") || className.startsWith("jdk.") || className.startsWith("sun.");
}

private static void assertEnhancedClass(String className) {
if (!ContinuationEnhancer.isEnhanced(className)) {
throw new ContinuationsException(
"Cannot use await/continuations when not all application classes on the callstack are properly enhanced. " +
"The following class is not enhanced: " + className);
}
}

protected static <T> void await(Future<T> future, F.Action<T> callback) {
Expand Down
9 changes: 5 additions & 4 deletions framework/test-src/play/mvc/ControllerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

import org.junit.Test;
import static org.junit.Assert.*;
import static play.mvc.Controller.shouldBeCheckedForEnhancement;
import static play.mvc.Controller.shouldNotBeEnhanced;

public class ControllerTest{
@Test
public void jdkAndPlayClassesShouldNeverBeenCheckedForEnhancement() {
assertTrue(shouldBeCheckedForEnhancement("sun.blah"));
assertTrue(shouldBeCheckedForEnhancement("play.foo"));
assertFalse(shouldBeCheckedForEnhancement("com.bar"));
assertTrue(shouldNotBeEnhanced("sun.blah"));
assertTrue(shouldNotBeEnhanced("jdk.base"));
assertTrue(shouldNotBeEnhanced("play.foo"));
assertFalse(shouldNotBeEnhanced("com.bar"));
}
}