Change-Id: I2a25b4149f927ee7940edf596e8cebaaa48dcd0dtags/7.4.0.beta1
@@ -115,6 +115,15 @@ public interface Constants { | |||
+ Constants.SERVLET_PARAMETER_LEGACY_PROPERTY_TOSTRING | |||
+ ". Supported values are 'false','warning','true'"; | |||
static final String CANNOT_ACQUIRE_CLASSLOADER_SEVERE = "\n" | |||
+ "=================================================================\n" | |||
+ "Vaadin was unable to acquire class loader from servlet container\n" | |||
+ "to load your application classes. Setup appropriate security\n" | |||
+ "policy to allow invoking Thread.getContextClassLoader() from\n" | |||
+ "VaadinService if you're not using custom class loader.\n" | |||
+ "NullPointerExceptions will be thrown later." | |||
+ "================================================================="; | |||
static final String URL_PARAMETER_THEME = "theme"; | |||
static final String SERVLET_PARAMETER_PRODUCTION_MODE = "productionMode"; | |||
@@ -164,4 +173,5 @@ public interface Constants { | |||
static final String PORTAL_PARAMETER_VAADIN_THEME = "vaadin.theme"; | |||
static final String PORTLET_CONTEXT = "PORTLET_CONTEXT"; | |||
} |
@@ -46,16 +46,6 @@ public class VaadinPortletService extends VaadinService { | |||
throws ServiceException { | |||
super(deploymentConfiguration); | |||
this.portlet = portlet; | |||
// Set default class loader if not already set | |||
if (getClassLoader() == null) { | |||
/* | |||
* The portlet is most likely to be loaded with a class loader | |||
* specific to the application instead of some generic system class | |||
* loader that loads the Vaadin classes. | |||
*/ | |||
setClassLoader(portlet.getClass().getClassLoader()); | |||
} | |||
} | |||
@Override | |||
@@ -162,7 +152,7 @@ public class VaadinPortletService extends VaadinService { | |||
if (Constants.PORTLET_CONTEXT.equals(staticFileLocation)) { | |||
return request.getContextPath(); | |||
} else{ | |||
} else { | |||
return trimTrailingSlashes(staticFileLocation); | |||
} | |||
} |
@@ -170,6 +170,10 @@ public abstract class VaadinService implements Serializable { | |||
+ classLoaderName, e); | |||
} | |||
} | |||
if (getClassLoader() == null) { | |||
setDefaultClassLoader(); | |||
} | |||
} | |||
/** | |||
@@ -1861,4 +1865,25 @@ public abstract class VaadinService implements Serializable { | |||
eventRouter.fireEvent(new ServiceDestroyEvent(this)); | |||
} | |||
/** | |||
* Tries to acquire default class loader and sets it as a class loader for | |||
* this {@link VaadinService} if found. If current security policy disallows | |||
* acquiring class loader instance it will log a message and re-throw | |||
* {@link SecurityException} | |||
* | |||
* @throws SecurityException | |||
* If current security policy forbids acquiring class loader | |||
* | |||
* @since | |||
*/ | |||
protected void setDefaultClassLoader() { | |||
try { | |||
setClassLoader(VaadinServiceClassLoaderUtil | |||
.findDefaultClassLoader()); | |||
} catch (SecurityException e) { | |||
getLogger().log(Level.SEVERE, | |||
Constants.CANNOT_ACQUIRE_CLASSLOADER_SEVERE, e); | |||
throw e; | |||
} | |||
} | |||
} |
@@ -0,0 +1,57 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.server; | |||
import java.security.AccessController; | |||
import java.security.PrivilegedAction; | |||
/** | |||
* Utility class used by {@link VaadinService#setDefaultClassLoader()}. | |||
* | |||
* @since | |||
* @author Vaadin Ltd | |||
*/ | |||
class VaadinServiceClassLoaderUtil { | |||
private static class GetClassLoaderPrivilegedAction implements | |||
PrivilegedAction<ClassLoader> { | |||
@Override | |||
public ClassLoader run() { | |||
return Thread.currentThread().getContextClassLoader(); | |||
} | |||
} | |||
/** | |||
* Called by {@link VaadinService#setDefaultClassLoader()} to acquire | |||
* appropriate class loader to load application's classes (e.g. UI). Calls | |||
* should be guarded by try/catch block to catch SecurityException and log | |||
* appropriate message. The code for this method is modeled after | |||
* recommendations laid out by JEE 5 specification sections EE.6.2.4.7 and | |||
* EE.8.2.5 | |||
* | |||
* @return Instance of {@link ClassLoader} that should be used by this | |||
* instance of {@link VaadinService} | |||
* @throws SecurityException | |||
* if current security policy doesn't allow acquiring current | |||
* thread's context class loader | |||
*/ | |||
static protected ClassLoader findDefaultClassLoader() | |||
throws SecurityException { | |||
return AccessController | |||
.doPrivileged(new VaadinServiceClassLoaderUtil.GetClassLoaderPrivilegedAction()); | |||
} | |||
} |
@@ -51,16 +51,6 @@ public class VaadinServletService extends VaadinService { | |||
throws ServiceException { | |||
super(deploymentConfiguration); | |||
this.servlet = servlet; | |||
// Set default class loader if not already set | |||
if (getClassLoader() == null) { | |||
/* | |||
* The servlet is most likely to be loaded with a class loader | |||
* specific to the application instead of some generic system class | |||
* loader that loads the Vaadin classes. | |||
*/ | |||
setClassLoader(servlet.getClass().getClassLoader()); | |||
} | |||
} | |||
private static boolean checkAtmosphereSupport() { |
@@ -19,6 +19,7 @@ import java.util.UUID; | |||
import java.util.logging.Level; | |||
import java.util.logging.Logger; | |||
import javax.servlet.ServletException; | |||
import javax.servlet.http.HttpServletRequest; | |||
import org.easymock.EasyMock; | |||
@@ -26,6 +27,7 @@ import org.junit.Assert; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import com.vaadin.server.MockServletConfig; | |||
import com.vaadin.server.ServiceException; | |||
import com.vaadin.server.VaadinService; | |||
import com.vaadin.server.VaadinServlet; | |||
@@ -36,6 +38,7 @@ import com.vaadin.server.communication.ServerRpcHandler.RpcRequest; | |||
import com.vaadin.shared.ApplicationConstants; | |||
import com.vaadin.tests.util.AlwaysLockedVaadinSession; | |||
import com.vaadin.tests.util.MockDeploymentConfiguration; | |||
import elemental.json.JsonException; | |||
/** | |||
@@ -62,10 +65,12 @@ public class CsrfTokenMissingTestServer { | |||
/** | |||
* Initialize the mock servlet and other stuff for our tests. | |||
* | |||
*/ | |||
@Before | |||
public void initMockStuff() throws ServiceException { | |||
public void initMockStuff() throws ServiceException, ServletException { | |||
mockServlet = new VaadinServlet(); | |||
mockServlet.init(new MockServletConfig()); | |||
mockDeploymentConfiguration = new MockDeploymentConfiguration(); | |||
mockService = new VaadinServletService(mockServlet, |
@@ -48,6 +48,8 @@ public class TestClassesSerializable extends TestCase { | |||
"com\\.vaadin\\.server\\.MockServletConfig", // | |||
"com\\.vaadin\\.server\\.MockServletContext", // | |||
"com\\.vaadin\\.server\\.Constants", // | |||
"com\\.vaadin\\.server\\.VaadinServiceClassLoaderUtil", // | |||
"com\\.vaadin\\.server\\.VaadinServiceClassLoaderUtil\\$GetClassLoaderPrivilegedAction", // | |||
"com\\.vaadin\\.server\\.communication\\.FileUploadHandler\\$SimpleMultiPartInputStream", // | |||
"com\\.vaadin\\.server\\.communication\\.PushRequestHandler.*", | |||
"com\\.vaadin\\.server\\.communication\\.PushHandler.*", // PushHandler |
@@ -80,11 +80,11 @@ public class TestStreamVariableMapping extends TestCase { | |||
private LegacyCommunicationManager createCommunicationManager() | |||
throws Exception { | |||
VaadinServlet servlet = new VaadinServlet(); | |||
servlet.init(new MockServletConfig()); | |||
VaadinServletService vss = new VaadinServletService(servlet, | |||
new MockDeploymentConfiguration()); | |||
servlet.init(new MockServletConfig()); | |||
return new LegacyCommunicationManager( | |||
new AlwaysLockedVaadinSession(vss)); | |||
} | |||
} |