Parcourir la source

Change the way classloader for VaadinService is selected (fixes #11295)

Change-Id: I2a25b4149f927ee7940edf596e8cebaaa48dcd0d
tags/7.4.0.beta1
Maciej Przepióra il y a 9 ans
Parent
révision
89bd22d61d

+ 10
- 0
server/src/com/vaadin/server/Constants.java Voir le fichier

@@ -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";

}

+ 1
- 11
server/src/com/vaadin/server/VaadinPortletService.java Voir le fichier

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

+ 25
- 0
server/src/com/vaadin/server/VaadinService.java Voir le fichier

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

+ 57
- 0
server/src/com/vaadin/server/VaadinServiceClassLoaderUtil.java Voir le fichier

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

}

+ 0
- 10
server/src/com/vaadin/server/VaadinServletService.java Voir le fichier

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

+ 6
- 1
server/tests/src/com/vaadin/tests/server/CsrfTokenMissingTestServer.java Voir le fichier

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

+ 2
- 0
server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java Voir le fichier

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

+ 1
- 1
server/tests/src/com/vaadin/tests/server/TestStreamVariableMapping.java Voir le fichier

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

}

Chargement…
Annuler
Enregistrer