The ClassLoader for loading Root instances is instead fetched using request.getDeploymentConfiguration().getClassLoader();tags/7.0.0.alpha2
@@ -40,6 +40,7 @@ import com.vaadin.service.ApplicationContext; | |||
import com.vaadin.terminal.AbstractErrorMessage; | |||
import com.vaadin.terminal.ApplicationResource; | |||
import com.vaadin.terminal.CombinedRequest; | |||
import com.vaadin.terminal.DeploymentConfiguration; | |||
import com.vaadin.terminal.RequestHandler; | |||
import com.vaadin.terminal.Terminal; | |||
import com.vaadin.terminal.VariableOwner; | |||
@@ -343,8 +344,6 @@ public class Application implements Terminal.ErrorListener, Serializable { | |||
private final boolean productionMode; | |||
private final ClassLoader classLoader; | |||
/** | |||
* @param applicationUrl | |||
* the URL the application should respond to. | |||
@@ -356,19 +355,14 @@ public class Application implements Terminal.ErrorListener, Serializable { | |||
* @param productionMode | |||
* flag indicating whether the application is running in | |||
* production mode. | |||
* @param classLoader | |||
* class loader to use for loading Root classes, | |||
* <code>null</code> indicates that the default class loader | |||
* should be used. | |||
*/ | |||
public ApplicationStartEvent(URL applicationUrl, | |||
Properties applicationProperties, ApplicationContext context, | |||
boolean productionMode, ClassLoader classLoader) { | |||
boolean productionMode) { | |||
this.applicationUrl = applicationUrl; | |||
this.applicationProperties = applicationProperties; | |||
this.context = context; | |||
this.productionMode = productionMode; | |||
this.classLoader = classLoader; | |||
} | |||
/** | |||
@@ -417,19 +411,6 @@ public class Application implements Terminal.ErrorListener, Serializable { | |||
public boolean isProductionMode() { | |||
return productionMode; | |||
} | |||
/** | |||
* Gets the class loader to use for loading Root classes, | |||
* <code>null</code> indicates that the default class loader should be | |||
* used. | |||
* | |||
* @return the class loader, or <code>null</code> if not defined. | |||
* | |||
* @see Application#getClassLoader() | |||
*/ | |||
public ClassLoader getClassLoader() { | |||
return classLoader; | |||
} | |||
} | |||
private final static Logger logger = Logger.getLogger(Application.class | |||
@@ -521,11 +502,6 @@ public class Application implements Terminal.ErrorListener, Serializable { | |||
*/ | |||
private Set<Integer> initedRoots = new HashSet<Integer>(); | |||
/** | |||
* The classloader that is used to load {@link Root} classes. | |||
*/ | |||
private ClassLoader classLoader; | |||
/** | |||
* Gets the user of the application. | |||
* | |||
@@ -640,7 +616,6 @@ public class Application implements Terminal.ErrorListener, Serializable { | |||
productionMode = event.isProductionMode(); | |||
properties = event.getApplicationProperties(); | |||
context = event.getContext(); | |||
classLoader = event.getClassLoader(); | |||
init(); | |||
applicationIsRunning = true; | |||
} | |||
@@ -1867,9 +1842,9 @@ public class Application implements Terminal.ErrorListener, Serializable { | |||
* The default implementation in {@link Application} creates a new instance | |||
* of the Root class returned by {@link #getRootClassName(WrappedRequest)}, | |||
* which in turn uses the {@value #ROOT_PARAMETER} parameter from web.xml. | |||
* If {@link #getClassLoader()} returns a {@link ClassLoader}, it is used | |||
* for loading the Root class. Otherwise the {@link ClassLoader} used to | |||
* load this class is used. | |||
* If {@link DeploymentConfiguration#getClassLoader()} for the request | |||
* returns a {@link ClassLoader}, it is used for loading the Root class. | |||
* Otherwise the {@link ClassLoader} used to load this class is used. | |||
* </p> | |||
* | |||
* @param request | |||
@@ -1890,7 +1865,8 @@ public class Application implements Terminal.ErrorListener, Serializable { | |||
throws RootRequiresMoreInformationException { | |||
String rootClassName = getRootClassName(request); | |||
try { | |||
ClassLoader classLoader = getClassLoader(); | |||
ClassLoader classLoader = request.getDeploymentConfiguration() | |||
.getClassLoader(); | |||
if (classLoader == null) { | |||
classLoader = getClass().getClassLoader(); | |||
} | |||
@@ -1909,16 +1885,6 @@ public class Application implements Terminal.ErrorListener, Serializable { | |||
} | |||
} | |||
/** | |||
* Get the class loader to use for loading Root classes. <code>null</code> | |||
* indicates that the default class loader should be used. | |||
* | |||
* @return the class loader to use, or <code>null</code> | |||
*/ | |||
protected ClassLoader getClassLoader() { | |||
return classLoader; | |||
} | |||
/** | |||
* Provides the name of the <code>Root</code> class that should be used for | |||
* a request. The class must have an accessible no-args constructor. |
@@ -74,4 +74,13 @@ public interface DeploymentConfiguration extends Serializable { | |||
*/ | |||
public String getApplicationOrSystemProperty(String propertyName, | |||
String defaultValue); | |||
/** | |||
* Get the class loader to use for loading classes loaded by name, e.g. | |||
* custom Root classes. <code>null</code> indicates that the default class | |||
* loader should be used. | |||
* | |||
* @return the class loader to use, or <code>null</code> | |||
*/ | |||
public ClassLoader getClassLoader(); | |||
} |
@@ -287,6 +287,12 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet | |||
return "/html"; | |||
} | |||
} | |||
public ClassLoader getClassLoader() { | |||
// Custom class loaders not currently supported in portlets (see | |||
// #8574) | |||
return null; | |||
} | |||
}; | |||
@Override | |||
@@ -857,7 +863,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet | |||
application.setLocale(locale); | |||
// No application URL when running inside a portlet | |||
application.start(new ApplicationStartEvent(null, | |||
applicationProperties, context, isProductionMode(), null)); | |||
applicationProperties, context, isProductionMode())); | |||
} | |||
} | |||
@@ -171,6 +171,14 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements | |||
public boolean isStandalone(WrappedRequest request) { | |||
return true; | |||
} | |||
public ClassLoader getClassLoader() { | |||
try { | |||
return AbstractApplicationServlet.this.getClassLoader(); | |||
} catch (ServletException e) { | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
}; | |||
static final String UPLOAD_URL_PREFIX = "APP/UPLOAD/"; | |||
@@ -1037,7 +1045,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements | |||
application.setLocale(locale); | |||
application.start(new ApplicationStartEvent(applicationUrl, | |||
applicationProperties, webApplicationContext, | |||
isProductionMode(), getClassLoader())); | |||
isProductionMode())); | |||
} | |||
} | |||
@@ -73,7 +73,7 @@ public class TransactionListenersConcurrency extends TestCase { | |||
app.start(new ApplicationStartEvent(new URL( | |||
"http://localhost/"), new Properties(), | |||
context, true, null)); | |||
context, true)); | |||
} catch (MalformedURLException e) { | |||
// TODO Auto-generated catch block | |||
e.printStackTrace(); |
@@ -6,9 +6,12 @@ import java.util.Properties; | |||
import junit.framework.TestCase; | |||
import org.easymock.EasyMock; | |||
import com.vaadin.Application; | |||
import com.vaadin.Application.ApplicationStartEvent; | |||
import com.vaadin.RootRequiresMoreInformationException; | |||
import com.vaadin.terminal.DeploymentConfiguration; | |||
import com.vaadin.terminal.WrappedRequest; | |||
import com.vaadin.ui.Root; | |||
@@ -50,12 +53,28 @@ public class CustomRootClassLoader extends TestCase { | |||
public void testWithNullClassLoader() throws Exception { | |||
Application application = createStubApplication(); | |||
application.start(new ApplicationStartEvent(null, new Properties(), | |||
null, false, null)); | |||
null, false)); | |||
Root root = application.getRootForRequest(null); | |||
Root root = application.getRootForRequest(createRequestMock(null)); | |||
assertTrue(root instanceof MyRoot); | |||
} | |||
private static WrappedRequest createRequestMock(ClassLoader classloader) { | |||
// Mock a DeploymentConfiguration to give the passed classloader | |||
DeploymentConfiguration configurationMock = EasyMock | |||
.createMock(DeploymentConfiguration.class); | |||
EasyMock.expect(configurationMock.getClassLoader()).andReturn( | |||
classloader); | |||
// Mock a WrappedRequest to give the mocked deployment configuration | |||
WrappedRequest requestMock = EasyMock.createMock(WrappedRequest.class); | |||
EasyMock.expect(requestMock.getDeploymentConfiguration()).andReturn( | |||
configurationMock); | |||
EasyMock.replay(configurationMock, requestMock); | |||
return requestMock; | |||
} | |||
/** | |||
* Tests that the ClassLoader passed in the ApplicationStartEvent is used to | |||
* load Root classes. | |||
@@ -68,9 +87,10 @@ public class CustomRootClassLoader extends TestCase { | |||
Application application = createStubApplication(); | |||
application.start(new ApplicationStartEvent(null, new Properties(), | |||
null, false, loggingClassLoader)); | |||
null, false)); | |||
Root root = application.getRootForRequest(null); | |||
Root root = application | |||
.getRootForRequest(createRequestMock(loggingClassLoader)); | |||
assertTrue(root instanceof MyRoot); | |||
assertEquals(1, loggingClassLoader.requestedClasses.size()); | |||
assertEquals(MyRoot.class.getName(), |
@@ -23,7 +23,8 @@ public class CustomLayoutUsingTemplate extends TestBase implements | |||
thisPackage = thisPackage.replaceAll( | |||
CustomLayoutUsingTemplate.class.getSimpleName() + "$", ""); | |||
String template = thisPackage + "template.htm"; | |||
InputStream is = getClassLoader().getResourceAsStream(template); | |||
InputStream is = getClass().getClassLoader().getResourceAsStream( | |||
template); | |||
try { | |||
layout = new CustomLayout(is); | |||
layout.addComponent(new Button( |