Не запускаетя EAR приложение: Vaadin 7.1.10 + Glassfish 4 + Netbeans 7.4

Здравствуйте.
Приложение диплоится в Glassfish 4 без ошибок, но при запуске выводится ошибка java.lang.ClassNotFoundException: com.r5.rtrade.app.RTradeApplication. Погуглил и нашел, что, если библиотеки Vaadin используются как общие (т.е. когда они
НЕ
находятся в папке WEB-INF\lib), то в приложении нужно переопределить загрузчик класса. Я это сделал, но теперь похоже, что Glassfish не может загрузить этот самый ClassLoader. Выводит ошибку: java.lang.RuntimeException: Could not find specified class loader: com.r5.rtrade.app.RTradeClassLoader
at com.vaadin.server.VaadinService.(VaadinService.java:157)
at com.vaadin.server.VaadinServletService.(VaadinServletService.java:52)
at com.vaadin.server.VaadinServlet.createServletService(VaadinServlet.java:189)
at com.vaadin.server.VaadinServlet.init(VaadinServlet.java:97)

Caused by: java.lang.ClassNotFoundException: com.r5.rtrade.app.RTradeClassLoader
at com.sun.enterprise.loader.ASURLClassLoader.findClassData(ASURLClassLoader.java:867)
at com.sun.enterprise.loader.ASURLClassLoader.findClass(ASURLClassLoader.java:744)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at com.vaadin.server.VaadinService.(VaadinService.java:150)
… 31 more

Раньше, когда использовал Vaadin 6.х, была подобная проблема, она решалась путем переопределения сервлета. А теперь непонятно что делать. Кто столкнулся с подобной проблемой, помогите пожалуйста.

[b]

  1. Вырезка из моего класса UI:
    [/b]
public abstract class AbstractWebApplication extends UI {
    private static final long serialVersionUID = 1L;
    
    private static final String MAIN_PAGE_NAME = "main";
    public static final String MAIN_TASK = "mainTask";

    @Override
    public final void init(VaadinRequest vr) {
        Subject user = SecurityUtils.getSubject();
        if (!user.isAuthenticated()) {
            LocaleUtil localeUtil = new LocaleUtil(getLocale());
            final CustomizedSystemMessages systemMessages = new CustomizedSystemMessages();
            systemMessages.setSessionExpiredCaption(localeUtil.getClientResource("vaadin.session.expired.caption"));
            systemMessages.setSessionExpiredMessage(localeUtil.getClientResource("vaadin.session.expired.message"));
            systemMessages.setCommunicationErrorCaption(localeUtil.getClientResource("vaadin.communication.error.caption"));
            systemMessages.setCommunicationErrorMessage(localeUtil.getClientResource("vaadin.communication.error.message"));
            systemMessages.setAuthenticationErrorCaption(localeUtil.getClientResource("vaadin.authentication.error.caption"));
            systemMessages.setAuthenticationErrorMessage(localeUtil.getClientResource("vaadin.authentication.error.message"));
            systemMessages.setInternalErrorCaption(localeUtil.getClientResource("vaadin.internal.error.caption"));
            systemMessages.setInternalErrorMessage(localeUtil.getClientResource("vaadin.internal.error.message"));
            systemMessages.setOutOfSyncCaption(localeUtil.getClientResource("vaadin.out.of.sync.caption"));
            systemMessages.setOutOfSyncMessage(localeUtil.getClientResource("vaadin.out.of.sync.message"));
            systemMessages.setCookiesDisabledCaption(localeUtil.getClientResource("vaadin.cookies.disabled.caption"));
            systemMessages.setCookiesDisabledMessage(localeUtil.getClientResource("vaadin.cookies.disabled.message"));

            getUserSession().getService().setSystemMessagesProvider(new SystemMessagesProvider() {

                @Override
                public SystemMessages getSystemMessages(SystemMessagesInfo systemMessagesInfo) {
                    return systemMessages;
                }
            });
            
            getUserSession().setAttribute("localeUtil", localeUtil);
            
            getPage().setTitle(getApplicationTitle());
            
            Navigator navigator = new Navigator(this, this);
            navigator.addView(LoginPage.PAGE_NAME, new LoginPage(getApplicationTitle()));
            
            addTaskPages(navigator);
            navigator.navigateTo(LoginPage.PAGE_NAME);
        }
    }
package com.r5.rtrade.app;

import com.r5.core.web.AbstractWebApplication;
import com.vaadin.annotations.PreserveOnRefresh;
import com.vaadin.annotations.Theme;
import com.vaadin.navigator.Navigator;

@PreserveOnRefresh
@Theme("rtrade")
public final class RTradeApplication extends AbstractWebApplication {

    @Override
    protected String getApplicationTitle() {
        return getLocaleUtil().getClientResource("app.title");
    }

    @Override
    protected void addTaskPages(Navigator navigator) {
    }
}


2. ClassLoader:

package com.r5.rtrade.app;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;

public class RTradeClassLoader extends ClassLoader {
    private final ClassLoader targetLoader;
    
    public RTradeClassLoader(ClassLoader p) {
        this.targetLoader = Thread.currentThread().getContextClassLoader();
        if (this.targetLoader==null) {
            throw new IllegalStateException("Cannot set up custom class loader: No context class loader set");
        }
    }

    @Override
    public URL getResource(String name) {
        return targetLoader.getResource(name);
    }

    @Override
    public InputStream getResourceAsStream(String name) {
        return targetLoader.getResourceAsStream(name);
    }

    @Override
    public Enumeration<URL> getResources(String name) throws IOException {
        return targetLoader.getResources(name);
    }

    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        return targetLoader.loadClass(name);
    }
}


3. Вырезка из web.xml:

<servlet>
        <servlet-name>rtradeServlet</servlet-name>
        <servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
        <init-param>
            <param-name>UI</param-name>
            <param-value>com.r5.rtrade.app.RTradeApplication</param-value>
        </init-param>
        <init-param>
            <param-name>widgetset</param-name>
            <param-value>com.r5.rtrade.widgetset.RTradeWidgetSet</param-value>
        </init-param>
        <init-param>
            <param-name>ClassLoader</param-name>
            <param-value>com.r5.rtrade.app.RTradeClassLoader</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>rtradeServlet</servlet-name>
        <url-pattern>/app/*</url-pattern>
    </servlet-mapping>

Когда приложение запускается, браузер показывает эту ошибку:

HTTP Status 500 - Internal Server Error

type Exception report

message Internal Server Error

description The server encountered an internal error that prevented it from fulfilling this request.

exception javax.servlet.ServletException: com.vaadin.server.ServiceException: com.vaadin.server.ServiceException: com.r5.rtrade.app.RTradeApplication could not be loaded

root causecom.vaadin.server.ServiceException: com.vaadin.server.ServiceException: com.r5.rtrade.app.RTradeApplication could not be loaded

root causecom.vaadin.server.ServiceException: com.r5.rtrade.app.RTradeApplication could not be loaded

root causejava.lang.ClassNotFoundException: com.r5.rtrade.app.RTradeApplication

note The full stack traces of the exception and its root causes are available in the GlassFish Server Open Source Edition 4.0 logs.

GlassFish Server Open Source Edition 4.0

Здравствуйте,
я в деталях по поводу использования кустарного класслоадера ничего Вам сказать не могу, но Вы вот пишите что

А что Вам мешает сейчас то отнаследоваться от VaadinServlet ?
Сделайте тоже самое что делали в Vaadin 6.
Пропишите затем свой класс web.xml вместо VaadinServlet и всё.
Другое дело что вам может понадобиться кустарный UIProvider, но давайте сначала с сервлетом разберёмся.

Добрый день.
Спасибо за отклик.
По поводу кустарного класслоадера я вычитал вот тут http://dev.vaadin.com/ticket/9809, и тупо скопировал исходник в целях проверки прокатит или нет, не прокатило ведь.
А вот на счет наследования от VaadinServlet, там похоже не обойтись одним переопределением VaadinServlet, похоже что придется переопределить еще и VaadinServletService. Просто подумал, неужели все так геморно.

А в Vaadin 6 проблема решалась вот так просто:

public final class RTradeServlet extends ApplicationServlet {

    @Override
    protected Class<? extends Application> getApplicationClass() throws ClassNotFoundException {
        return RTradeApplication.class;
    }

    @Override
    protected Application getNewApplication(HttpServletRequest request) throws ServletException {
        return new RTradeApplication();
    }
}

Понятно, да, в 7 так не получится.
Насчёт гемора - это к R&D.
А в приведённой ссылке на баг вроде же описано как это чинится в 7.
Сервлет придётся переодпределить, создать кустарный класслоадер.
VaadinServletService переопределять причин не вижу.
В сервлете нужно только метод createServletService() свой написать.
Имплементация:

VaadinServletService service=super.createServletService();
service.setClassLoader(new RTradeClassLoader());

В web.xml, насколько я понял, ничего прописывать не надо.
Не так и сложно.