Hello to all.
The application deploys into Glassfish 4 without any errors, but when running occurs exception java.lang.ClassNotFoundException: com.r5.rtrade.app.RTradeApplication.
On the forum I found that: custom class loader is required when using Vaadin as shared libs (rather than in WEB-INF/lib).
I specified a custom class loader, but now occurs exception 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
It seems that Glassfish can not load my custom ClassLoader.
Previously, when using Vaadin 6.x, had a similar problem, it was solved by overriding the ApplicationServlet. And now it is unclear what to do. Please help me.
[b]
- My UI class:
[/b]
public abstract class AbstractWebApplication extends UI {
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. My custom class loader:
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>