Browse Source

Remove classloader field to make Application serializable (#8644)

The ClassLoader for loading Root instances is instead fetched using
request.getDeploymentConfiguration().getClassLoader();
tags/7.0.0.alpha2
Leif Åstrand 12 years ago
parent
commit
4155cb0d2c

+ 7
- 41
src/com/vaadin/Application.java View File

@@ -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.

+ 9
- 0
src/com/vaadin/terminal/DeploymentConfiguration.java View File

@@ -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();
}

+ 7
- 1
src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java View File

@@ -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()));
}
}


+ 9
- 1
src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java View File

@@ -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()));
}
}


+ 1
- 1
tests/server-side/com/vaadin/tests/server/TransactionListenersConcurrency.java View File

@@ -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();

+ 24
- 4
tests/server-side/com/vaadin/tests/server/component/root/CustomRootClassLoader.java View File

@@ -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(),

+ 2
- 1
tests/testbench/com/vaadin/tests/components/customcomponent/CustomLayoutUsingTemplate.java View File

@@ -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(

Loading…
Cancel
Save