Java WAR - Load Spring beans from an external JAR - spring-mvc

I would like to load inside my Spring MVC Web Application (packaged as WAR) some Spring framework beans annotated with #Service from an external jar, which is in charge of accessing a database and located in the classpath under /WEB-INF/lib. If possible, it would be desirable to load them automatically using the #Autowired annotation.
I have followed successfully the solution in this link1:
this.ctx = new ClassPathXmlApplicationContext("services-context.xml");
this.myAService = ctx.getBean("myAService");
However, this solution uses Spring API function getBean which is considered a bad practice (see link2).
I also tried, without luck two more things to load the external jar´s applicationContext:
WAR´s appContext.xml:
<import resource="classpath*:/WEB-INF/lib/pathToExternalJar/applicationContext.xml">
WAR´s web xml -> load the jar´s appContext as described here (link3). (e.g. *applicationContext.xml):
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:localSpringContext.xml
classpath:*applicationContext.xml
</param-value>
</context-param>
What is the best approach to load those beans properly and how should it be done?

WAR´s appContext.xml and WAR´s web xml are both feasible. If you need to run integration tests based on both localSpringContext.xml and external jar's applicationContext.xml frequently, I recommend the WAR´s appContext.xml approach.
Updated1:
WAR´s appContext.xml:
<import resource="classpath:{classpath}/applicationContext.xml"/>
WAR´s web xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:localSpringContext.xml
classpath:{classpath}/applicationContext.xml
</param-value>
</context-param>
For example, if your applicationContext.xml is under package :com/gmail/hippoom
you can get it by classpath:com/gmail/hippoom/applicationContext.xml or classpath*:applicationContext.xml with wildcard.

Related

Weblogic upgrade to 12c: deployment fails because url mapped to multiple servlet

I've recently setup a new Weblogic 12c environment. On deploying an application that I know works in Weblogic 11g I get the error "The url-pattern /resources/* in web application is mapped to multiple Servlets."
The mapping it's referring to is in the web.xml inside the application.ear that's being deployed, but it's only mapped once:
<servlet-mapping>
<servlet-name>velocity</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
The project doesn't contain any other references to the url pattern /resources/*, can someone explain where the duplicated mapping is coming from and how I can work around it?
The closest issue I could find is this: https://bugster.forgerock.org/jira/si/jira.issueviews:issue-html/OPENAM-7947/OPENAM-7947.html, which has been marked as unreproducible.
Full stack trace from deployment:
<Error> <Deployer> <BEA-149205> <Failed to initialize the application "<application_name>" due to error weblogic.application.ModuleException: weblogic.management.DeploymentException: [HTTP:101401]The url-pa
ttern /resources/* in web application <application_name> is mapped to multiple Servlets.
weblogic.application.ModuleException: weblogic.management.DeploymentException: [HTTP:101401]The url-pattern /resources/* in web application <application_name> is mapped to multiple Servlets.
at weblogic.application.internal.ExtensibleModuleWrapper.prepare(ExtensibleModuleWrapper.java:114)
at weblogic.application.internal.flow.ModuleListenerInvoker.prepare(ModuleListenerInvoker.java:100)
at weblogic.application.internal.flow.ModuleStateDriver$1.next(ModuleStateDriver.java:192)
at weblogic.application.internal.flow.ModuleStateDriver$1.next(ModuleStateDriver.java:187)
at weblogic.application.utils.StateMachineDriver$ParallelChange.run(StateMachineDriver.java:83)
at weblogic.application.utils.StateMachineDriver.nextStateInParallel(StateMachineDriver.java:144)
at weblogic.application.internal.flow.ModuleStateDriver.parallelPrepare(ModuleStateDriver.java:46)
at weblogic.application.internal.flow.DeploymentCallbackFlow.prepare(DeploymentCallbackFlow.java:75)
at weblogic.application.internal.flow.DeploymentCallbackFlow.prepare(DeploymentCallbackFlow.java:55)
at weblogic.application.internal.BaseDeployment$1.next(BaseDeployment.java:731)
at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:45)
at weblogic.application.internal.BaseDeployment.prepare(BaseDeployment.java:243)
at weblogic.application.internal.EarDeployment.prepare(EarDeployment.java:66)
at weblogic.application.internal.DeploymentStateChecker.prepare(DeploymentStateChecker.java:158)
at weblogic.deploy.internal.targetserver.AppContainerInvoker.prepare(AppContainerInvoker.java:65)
at weblogic.deploy.internal.targetserver.AppDeployment.prepare(AppDeployment.java:158)
at weblogic.management.deploy.internal.DeploymentAdapter$1.doPrepare(DeploymentAdapter.java:41)
at weblogic.management.deploy.internal.DeploymentAdapter.prepare(DeploymentAdapter.java:193)
at weblogic.management.deploy.internal.AppTransition$1.transitionApp(AppTransition.java:31)
at weblogic.management.deploy.internal.ConfiguredDeployments$2.doItem(ConfiguredDeployments.java:684)
at weblogic.management.deploy.internal.parallel.BucketInvoker.invoke(BucketInvoker.java:138)
at weblogic.management.deploy.internal.ConfiguredDeployments.transitionAppsParallel(ConfiguredDeployments.java:692)
at weblogic.management.deploy.internal.ConfiguredDeployments.prepare(ConfiguredDeployments.java:322)
at weblogic.management.deploy.internal.ConfiguredDeployments.deploy(ConfiguredDeployments.java:202)
at weblogic.management.deploy.internal.DeploymentServerService.resume(DeploymentServerService.java:207)
at weblogic.management.deploy.internal.DeploymentServerService.start(DeploymentServerService.java:129)
at weblogic.server.AbstractServerService.postConstruct(AbstractServerService.java:76)
at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.glassfish.hk2.utilities.reflection.ReflectionHelper.invoke(ReflectionHelper.java:1262)
at org.jvnet.hk2.internal.ClazzCreator.postConstructMe(ClazzCreator.java:332)
at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:374)
at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
at org.glassfish.hk2.runlevel.internal.AsyncRunLevelContext.findOrCreate(AsyncRunLevelContext.java:232)
at org.glassfish.hk2.runlevel.RunLevelContext.findOrCreate(RunLevelContext.java:85)
at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2020)
at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:114)
at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:88)
at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$QueueRunner.oneJob(CurrentTaskFuture.java:1213)
at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$QueueRunner.run(CurrentTaskFuture.java:1144)
at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:666)
at weblogic.invocation.ComponentInvocationContextManager._runAs(ComponentInvocationContextManager.java:348)
at weblogic.invocation.ComponentInvocationContextManager.runAs(ComponentInvocationContextManager.java:333)
at weblogic.work.LivePartitionUtility.doRunWorkUnderContext(LivePartitionUtility.java:54)
at weblogic.work.PartitionUtility.runWorkUnderContext(PartitionUtility.java:41)
at weblogic.work.SelfTuningWorkManagerImpl.runWorkUnderContext(SelfTuningWorkManagerImpl.java:640)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:406)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:346)
If you use web annotations in java code, you don't have to declare the servlet in the web.xml file any more.
You can try by removing the corresponding "servlet" and "servlet-mapping" tags in web.xml
It seems that WebLogic 12.1.3 can deal with double declaration (inline annotation & xml) but not anymore in WebLogic 12.2.
I had this error with #webservice annotation when I specified the "serviceName" parameter and when I declared the servlet in web.xml file with the same value.
The issue doesn't exist in version 12.1.3 (which happened to be the version we were meant to be upgrading to).
Weblogic as of version 12.2.1.3 automatically registers a JAX-RS servlet to the path /resources/* in certain scenarios (e.g. some dependency like jackson-jaxrs-json-provider "requests" it via annotation/spi/moduleinfo). But if this path is already registered by another service the mentioned error is thrown.
There are 3 possible solutions one can try:
In our case the issue was coming from classpath scanning for web services components, and finding annotated services in the webservices-rt jar. That scanning needed to be switched off.
Setting the metadata-complete attribute to true in the web.xml descriptor if your Web application does not have any annotations and if you have the version set to 2.5 or higher to avoid unnecessary scanning of the Web applications classes for annotations. E.g.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
<servlet>
<servlet-name>sample</servlet-name>
<servlet-class>Sample</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sample</servlet-name>
<url-pattern>/sample</url-pattern>
</servlet-mapping>
</web-app>
Alternatively, you can turn off annotation processing and DI for all the Web applications by setting -Dweblogic.servlet.DIDisabled=true flag when starting WebLogic Server.
Registering another path for jersey in the web.xml to e.g. /jersey/*
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/jersey/*</url-pattern>
</servlet-mapping>
Try removing the FATP jars which were added after 12.2 upgrade. This worked for me.

ServletContextListener not being invoked

I creating a Java EE 7 project using Eclipse Maven plugin. My problem is when I run the application the class that implements SerlvetContextListener does not get invoked. What is causing this problem?
#WebListener
public class ApplicationContextListener implements ServletContextListener{
#Override
public void contextInitialized(ServletContextEvent sce)
{
Request request = new HttpRequest(sce);
new Thread (request).start();
HibernateUtil.getSessionFactory();
}
#Override
public void contextDestroyed(ServletContextEvent sce)
{
}
}
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<listener>com.kyrogaming.AppServletContextListener</listener>
<!-- Jersey Mapping -->
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.kyrogaming.webservices</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
<!-- end Jersey Mapping -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
To summarize JNL's and Ted Goddard's answers:
For a ServletContextListener (or other listeners, such as a ServletContextAttributeListener or a ServletRequestAttributeListener) to be loaded by the servlet container, you need to tell the container about it. As described in the API docs, there are three ways to do this:
Declare it in the deployment descriptor (web.xml):
com.kyrogaming.AppServletContextListener
or annotate its class with #WebListener (see "Note about annotations" below)
or register it programatically, via the methods in ServletContext, such as addListener().
Note about annotations
Method 1) and 3) will always work. For method 2) (annotations) to work, the servlet container must be configured to scan the classes in the classpath, to find the annotated listener classes.
The webapp's own classes (under WEB-INF/classes) and libraries (JARs under WEB-INF/lib) will not be scanned if the web.xml contains the attribute metadata-complete="true" (the attribute defaults to false). See the Java Servlet Specification Version 3.0, chapter 8.1, "Annotations and pluggability".
In a web application, classes using annotations will have their annotations processed only if they are located in the WEB-INF/classes directory, or if they are packaged in a jar file located in WEB-INF/lib within the application. The web application deployment descriptor contains a new “metadata-complete” attribute on the web-app element. The “metadata-complete” attribute defines whether the web descriptor is complete, or whether the class files of the jar file should be examined for annotations and web fragments at deployment time. If “metadata-complete” is set to "true", the deployment tool MUST ignore any servlet annotations present in the class files of the application and web fragments. If the metadata-complete attribute is not specified or is set to "false", the deployment tool must examine the class files of the application for annotations, and scan for web fragments.
So, to allow the container to find annotated classes in JARs, make sure the web.xml sets metadata-complete="false", or does not set it at all.
Note that setting this may delay the application startup; see for example What to do with annotations after setting metadata-complete="true" (which resolved slow Tomcat 7 start-up)? .
Unfortunately, that still does not explain why the ServletContextListener in the question is not loaded. Note that the web.xml in the question does not metadata-complete, meaning it defaults to false, thus classpath scanning is enabled. There is probably some other problem; this checklist hopefully helps in finding it.
Using metadata-complete="false" in web.xml fixed this issue for me.
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="false">
In web.xml you also need to specify the <listener-class>.
<listener>
<listener-class>
com.kyrogaming.AppServletContextListener
</listener-class>
</listener>
For the record, I'm adding yet another possible (and rather vicious) cause of ServletContextListener not being invoked.
This can happen when you have a java.lang.LinkageError, that is when you forgot to add <scope>provided</scope> to your javax.servlet-api dependency.
In such a case the listener instance is created but only the static part is executed, not the contextInitialized and contextDestroyed methods.
You shall discover only when you invoke some servlet, as the linkage error is not raised during listener instantiation.
There is one other extremely rare scenario which can cause this. (which took me 4 hours to uncover)
If you're using Tomcat10 then you can't use javax.servlet library in your maven/gradle.
Tomcat9 still has javax.servlet, but Tomcat10 migrated to jakarta.servlet
Tomcat10 expects to have Listener class that uses jakarta.servlet.ServletContextListener
So use this maven dependency: (scope is provided, because Tomcat10 already has such library)
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
The running container might need to explicitly allow scanning for annotations:
Ex for jetty:
cd [JETTY_BASE]
java -jar [JETTY_HOME]/start.jar --add-module=annotations
In a Spring-Boot 1.3+ scenario, you need to have the package for the class annotated with #WebListener (and #WebFilter, #WebServlet) fall under the #ServletComponentScan package scope.
Per Baeldung.

How does Spring 3.1 Java based configuration work

Just a general question, when you define a Java based configuration web app. Ie.e have a class for : ApplicationContext and a WebApplicationInitializer class.
How does Spring know it has to load the beans, as no xml config files exists.. how does tomcat know anything about the webapp without a web.xml
Its a newbie question.. i appreciate that. :)
See this blog post from SpringSource blog, important part about web.xml has an example, basically you point to JavaConfigWebApplicationContext instead of default XmlWebApplicationContext in DispatcherServlet's <init-param>:
<web-app>
<!-- Configure ContextLoaderListener to use JavaConfigWebApplicationContext
instead of the default XmlWebApplicationContext -->
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.config.java.context.JavaConfigWebApplicationContext</param-value>
</context-param>
<!-- Configuration locations must consist of one or more comma- or space-delimited
fully-qualified #Configuration classes -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>example.RootApplicationConfig</param-value>
</context-param>
<!-- Bootstrap the root application context as usual using ContextLoaderListener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Declare a Spring MVC DispatcherServlet as usual -->
<servlet>
<servlet-name>dispatcher-servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- Configure DispatcherServlet to use JavaConfigWebApplicationContext
instead of the default XmlWebApplicationContext -->
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.config.java.context.JavaConfigWebApplicationContext</param-value>
</init-param>
<!-- Again, config locations must consist of one or more comma- or space-delimited
and fully-qualified #Configuration classes -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>example.web.WebBeansConfig</param-value>
</init-param>
</servlet>
</web-app>
I have a VERY GOOD WAY to help you learn Spring MVC if you have Maven up and running.
IF SO: go to your command line (Cygwin) I use...
mvn archetype:generate
It will ask for an 'archetype number'. For you... type 16
Enter the group ID which is just the main package.
Enter Artifact ID which is your project name.
SNAP-SHOT --- just press enter and same with version.
Package - is the same as your group ID name. EX: com.spring
Confirm it by entering the letter 'y' and press enter.
DO all of the above after your are in your workspace directory. That way it is created there.
You can do "mvn eclipse:eclipse" to load it in Eclipse OR you can just import it. I prefer the old fashioned importing an existing project.
Everything will be 'already' set up for you in terms of ALL configuration (Java-Based) which is good for you. It will have all the Maven dependencies you need as well already in your pom.xml. You can add or take from it if you want.
The point here is that you will have a running project already and you can play with it from there. I create all my projects like this at first and erase what I don't need and add what I do and then go from there.
Good luck!!!
Anywho... add this to your web.xml. This will help you in your answer. Research this below:
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

could not find Factory: javax.faces.context.FacesContextFactory

I notice that when trying to setup my JSF 2 webapp running on jetty, i have this error :
java.lang.IllegalStateException: Application was not properly
initialized at startup, could not find Factory:
javax.faces.context.FacesContextFactory
which is easily solved by adding this to my web.xml
<listener>
<listener-class>
com.sun.faces.config.ConfigureListener
</listener-class>
</listener>
I've tried searching for a detailed explanation but in futile ..
jetty-maven-plugin:8.0.3.v20111011:run + jdk 7 + eclipse indigo
And here's my maven dependency :
<dependencies>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.faces</artifactId>
<version>2.1.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
Here's my web.xml :
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>Basic Setup Web Application</display-name>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
<listener>
<listener-class>
com.sun.faces.config.ConfigureListener
</listener-class>
</listener>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
</web-app>
and here's the output of the jetty plugin :
[INFO] <<< jetty-maven-plugin:8.0.3.v20111011:run (default-cli) # BasicSetup <<<
[INFO]
[INFO] --- jetty-maven-plugin:8.0.3.v20111011:run (default-cli) # BasicSetup ---
[INFO] Configuring Jetty for project: BasicSetup Maven Webapp
[INFO] webAppSourceDirectory C:\Users\albert\workspace\BasicSetup\src\main\webapp does not exist. Defaulting to C:\Users\albert\workspace\BasicSetup\src\main\webapp
[INFO] Reload Mechanic: automatic
[INFO] Classes = C:\Users\albert\workspace\BasicSetup\target\classes
[INFO] Context path = /basicSetup
[INFO] Tmp directory = C:\Users\albert\workspace\BasicSetup\target\tmp
[INFO] Web defaults = org/eclipse/jetty/webapp/webdefault.xml
[INFO] Web overrides = none
[INFO] web.xml file = file:/C:/Users/albert/workspace/BasicSetup/src/main/webapp/WEB-INF/web.xml
[INFO] Webapp directory = C:\Users\albert\workspace\BasicSetup\src\main\webapp
2011-10-25 14:24:51.091:INFO:oejs.Server:jetty-8.0.3.v20111011
2011-10-25 14:24:51.334:INFO:oejpw.PlusConfiguration:No Transaction manager found - if your webapp requires one, please configure one.
2011-10-25 14:24:52.108:INFO:oejsh.ContextHandler:started o.m.j.p.JettyWebAppContext{/basicSetup,[file:/C:/Users/albert/workspace/BasicSetup/src/main/webapp/, jar:file:/C:/Users/albert/.m2/repository/org/glassfish/javax.faces/2.1.3/javax.faces-2.1.3.jar!/META-INF/resources/]},file:/C:/Users/albert/workspace/BasicSetup/src/main/webapp/
2011-10-25 14:24:52.108:INFO:oejsh.ContextHandler:started o.m.j.p.JettyWebAppContext{/basicSetup,[file:/C:/Users/albert/workspace/BasicSetup/src/main/webapp/, jar:file:/C:/Users/albert/.m2/repository/org/glassfish/javax.faces/2.1.3/javax.faces-2.1.3.jar!/META-INF/resources/]},file:/C:/Users/albert/workspace/BasicSetup/src/main/webapp/
2011-10-25 14:24:52.108:INFO:oejsh.ContextHandler:started o.m.j.p.JettyWebAppContext{/basicSetup,[file:/C:/Users/albert/workspace/BasicSetup/src/main/webapp/, jar:file:/C:/Users/albert/.m2/repository/org/glassfish/javax.faces/2.1.3/javax.faces-2.1.3.jar!/META-INF/resources/]},file:/C:/Users/albert/workspace/BasicSetup/src/main/webapp/
2011-10-25 14:24:52.149:WARN:/basicSetup:unavailable
java.lang.IllegalStateException: Application was not properly initialized at startup, could not find Factory: javax.faces.context.FacesContextFactory
at javax.faces.FactoryFinder$FactoryManager.getFactory(FactoryFinder.java:967)
at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:316)
at javax.faces.webapp.FacesServlet.init(FacesServlet.java:302)
at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:456)
at org.eclipse.jetty.servlet.ServletHolder.doStart(ServletHolder.java:276)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:779)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:255)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1212)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:610)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:453)
at org.mortbay.jetty.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:256)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:224)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:167)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:224)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:89)
at org.eclipse.jetty.server.Server.doStart(Server.java:262)
at org.mortbay.jetty.plugin.JettyServer.doStart(JettyServer.java:65)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:511)
at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:364)
at org.mortbay.jetty.plugin.JettyRunMojo.execute(JettyRunMojo.java:514)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:107)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:319)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:534)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
[INFO] Started Jetty Server
2011-10-25 14:24:52.165:INFO:oejs.AbstractConnector:Started SelectChannelConnector#0.0.0.0:8080 STARTING
[INFO] Starting scanner at interval of 10 seconds.
Any thoughts ?
This listener is since JSF 1.x supposed to be automatically registered by the jsf_core.tld tag library definition file. You can find it in the /META-INF folder of the JSF implementation JAR file. In case of Mojarra 2.1.3 (which you seem to be using according the logs), the listener is registered as follows from line 80 and on:
<!-- ============== Configuration Listener ============== -->
<!--
This ServletContextListener initializes the runtime environment
of the JavaServer Faces Reference Implementation when a web
application including it is initialized by the container.
-->
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
However, this is apparently not been picked up properly by Jetty. I've also read somewhere that when the FacesServlet is been initialized before the TLD file is been processed, then you will also get exactly this exception. Perhaps this is happening in Jetty. To exclude the one and other, try to remove the <load-on-startup> entry so that it will be loaded only on first concrete HTTP request, far after the TLD is been processed. In any way, explicitly registering the listener in web.xml should indeed solve it.
Further, since JSF 2.x, in addition to the TLD file, the listener is also supposed to be automatically registered by a ServletContainerInitializer implementation in the JAR file in order to workaround a Glassfish 3 bug. In Mojarra 2.x this is the com.sun.faces.config.FacesInitializer class which has the following lines starting at line 131:
// The following line is temporary until we can solve an ordering
// issue in V3. Right now the JSP container looks for a mapping
// of the FacesServlet in the web.xml. If it's not present, then
// it assumes that the application isn't a faces application. In this
// case the JSP container will not register the ConfigureListener
// definition from our TLD nor will it parse cause or JSP TLDs to
// be parsed.
servletContext.addListener(com.sun.faces.config.ConfigureListener.class);
This works in Servlet 3.0 containers only, such as Tomcat 7, Glassfish 3, Jetty 8 (supposedly!), etc. You seem to be using Jetty 8.0 which should thus comply Servlet 3.0, but your web.xml is declared conform Servlet 2.5, so the container will run in Servlet 2.5 fallback modus. Changing your web.xml to conform Servlet 3.0 should trigger this initializer.
One more resolve:
I got this error after I created java files on the fly with CXF from wsdl.
JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();
Client client = factory.createClient(wsdlURL, serviceName);
CXF puts its own ClassLoader (instance of URLClassLoader) to the Thread's classloader. It works the normal way, until user's thread gets into JSF's FactoryFinder, which is cached by the ClassLoader as the key.
Because the ClassLoader changed, it creates a new FactoryManager, which cannot be initialized, because the implementation instance lists are removed when the original FactoryManager initiated. Because of it, the Implementation classes are not found, hence the IllegalStateException is thrown.
Solution: backup the original ClassLoader before CXF's createClient, save the URLClassLoader in a variable and put back the original ClassLoader to the Thread.
When you want to access a dynamic class from CXF, search it through the URLClassLoader you put in a variable.
I had this issue on my project, in that included two jar file to lib folder now my problem salved.Thank You
com.sun.faces:jsf-api:2.2.9
com.sun.faces:jsf-impl:2.2.9

Glassfish 3 - Loading images from a static server

I'm trying to load images (and other static content) from a server outside of my web application which is deployed to Glassfish v3. I have the following configs in the web.xml but it does not work on Glassfish (but it works on Tomcat):
<servlet>
<servlet-name>ExternalImagesServlet</servlet-name>
<servlet-class>com.example.servlet.HttpProxyServlet</servlet-class>
<init-param>
<param-name>RemoteURI</param-name>
<param-value>http://ip.of.second.server/website-files</param-value>
</init-param>
<init-param>
<param-name>AllowedContentTypes</param-name>
<param-value>image/gif,image/jpeg,image/png</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ExternalImagesServlet</servlet-name>
<url-pattern>/images/*</url-pattern>
</servlet-mapping>
Where ip.of.second.server is an actual IP address of the server. I have the file called website-files.xml defined as follow:
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="d:/internet/website/images" />
And website-files.xml is saved to glassfish\domains\domain1\config directory. But Glassfish does not pick up this config file.
I have looked at Oracle Glassfish configuration doco but there's no mention on how you can reference images from a different server.
Please help.
I have solved it based on an old thread relating to Glassfish version 2 that I found on Google after two days of search.
In case anyone is interested in the solution, here it is:
1) Create a file called sun-web.xml directly under Webcontent\WEB-INF directory and add the following configuration to this file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD GlassFish Application Server 3.0 Servlet 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_3_0-0.dtd">
<sun-web-app>
<property name="alternatedocroot_1" value="from=/images/* dir=d:/internet/website" />
<property name="alternatedocroot_2" value="from=/files/* dir=d:/internet/website" />
</sun-web-app>
2) Remove the servlet and servlet-mapping configurations from web.xml file (like I did above). Note: The above would work if you were to use Tomcat.
3) Delete the website-files.xml from glassfish\domains\domain1\config directory as this file is not needed by Glassfish: Note: This file is needed by Tomcat.

Resources