Using component-scan in a web project - spring-mvc

I have an Eclipse "Dynamic Web Project" and a Tomcat server configured in Eclipse to use that project. I have a file extension mapped to a servlet, and in the servlet config I have a component-scan element setup like this:
<context:component-scan base-package="com.mycompany.web" />
When my web server starts up, I see this error message in the log:
May 6, 2011 9:50:23 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Allocate exception for servlet cap
java.lang.IllegalArgumentException: Resource path [C:\...\src\main\webapp\WEB-INF\classes\com\mycompany\web] does not denote a directory
That directory does not exist (except in the packaged .war file). However, the com.mycompany.web package does exist.
Is there another way to do a component-scan? It needs to either look in another folder, or somehow find it in my project or something...

It doesn't appear to be possible to do a component-scan in this way. It does a directory listing, which I guess isn't possible when the class files aren't physically located where Spring is expecting. I solved this just by not using a component-scan, and listing the controllers in the spring config like this:
<context:annotation-config />
<bean class="com.mycompany.web.MyController"/>
Annotations in the controller still work, so listed the controllers manually is the only extra step.

it's possible to do what you want, but you need a little extra configuration.
You can annotate your classes with #Controller or #Repository or other Spring stereotype annotations and Spring will pick them up automatically.
Or you can give context:component-scan a bit more info. Example:
<context:component-scan base-package="com.mycompany.web">
<!-- scan all classes in the com.mycompany.web package (but
not in subpackages) -->
<context:include-filter type="aspectj" expression="com.mycompany.web.*"/>
<!-- or if you want to include subpackages this config scans all
classes in com.mycompany.web.special and in its subpackages
(that's what the ..* means) -->
<context:include-filter type="aspectj" expression="com.mycompany.web.special..*"/>
</context:component-scan>
Finally, if you don't like using aspectj, context:include-filter's type can be a regular expression, custom annotation, etc. See this link for more info.

Related

Weblogic 12.2.1.3 webjar-locator not working

I have a multi module Maven Spring project and can't get webjars-locator-weblogic to work with it.
The webjars are reachable and the mapping is declared as:
<mvc:resources mapping="/webjars/**" location="classpath:META-INF/resources/webjars/" />
However, if i try to use the version agnostic link, the response is always 404. Have already tried with both webjar-locator and webjar-locator-weblogic dependencies with no success.
Have been using this exact same configuration with other servers and never had any issues.
What am i missing?

Server equivalent to application web.xml

I'm running a .war file in 3 different Servers, but for each server I need a different description in the web.xml file, that will be accessed like:
context.getInitParameter("CompanyKey")
Is there a equivalent for a server file? It's being a pain to change this file at each deploy.
Im currently using GlassFish 4.1
After some search, I found out that GlassFish holds a file called default-web.xml in the config folder.
All variables listed here takes precedence over the variables in the application (war) web.xml.
I just transferred my variables there and it worked!
Some helpful links for those searching about web.xml, context.xml and default-web.xml (it helped me to get to my answer):
https://blogs.oracle.com/alexismp/entry/how_to_use_tomcat_context
http://docs.oracle.com/cd/E19798-01/821-1752/geurd/index.html
How can I share a variable or object between two or more Servlets?
What is the glassfish alternative to context.xml

How do I deploy application classes and Spring config files to Tomcat as a single jar?

Currently I create a new war file for each change but the changes are taking place in only a few classes and the Spring applicationContext.xml.
I would like to just update a jar file that contains these classes and not continually re-deploy hundreds of files that have not changed. I can create the jar easily enough but where do I put it and do I have to tell Spring to look in a specific jar for its' config files?
It is quite impossible to hot-redeploy code in Tomcat without using extra tools like JRebel or custom JVM agents.
But it is possible to modularize you application by:
1: Putting JARs to $TOMCAT_HOME/lib. Never do this, this solution is good only for simple cases.
2: Tune context.xml, putting Loader in it, like below:
<Context antiJARLocking="true" path="/">
<Loader className="org.apache.catalina.loader.VirtualWebappLoader" virtualClasspath="${catalina.base}/my-app-plugins/*.jar"/>
</Context>
This will enable you putting JAR file in $TOMCAT_HOME/my-app-plugins and thet will be added to the classpath of you app. You should put context.xml to the src/main/webapp/META-INF folder (Maven layout). However, restart is still needed.
3: Use OSGi. May be an overkill.

problem with the injection of an EJB that resides in a jar

I have some problems regarding the EJB injection and I haven't been able to find a solution anywhere.
My situation is the following: I have an EAR file that includes a WAR and several JARs, all listed in the application.xml file. All is working fine for this part.
The problems come out when I try to add what we can call a “plugin system”.
I have a JAR with inside some .xhtml pages, backing beans and EJBs. This JAR, if needed, is inserted inside the EAR in a specific directory (let's call it “plugins”) and is detected from the application at startup.
When the JAR is detected it's path is added to the WAR class loader so all the pages and the backing bean are detected without problems. What is not working is the injection of the EJBs (I tried to use the notation #EJB, #Inject, the lookup...). I can't inject any of the EJBs that is inside the JAR plugin.
My guess is that the application server treats the JAR as a simple library module and doesn't look for any EJB inside it, so they are inside the JAR but not usable from the application.
My question is: there's a way of having this working? I tried to add the JAR in the EAR's MANIFEST.MF but nothing changed...
the application server i'm using is glassfish 3.0. About the application.xml: there's no reference in it about the JARs that are part of what i called "plugin system". This because i detect them when i deploy (or i restart) the application in the application server, so they may or may not be inside the system and i don't really know that before the system is started.
Each plugin JAR is a "collection" of pages and functionalities that can be added or removed from the system dynamically (more less like a real plugin system).
My EAR structure is the following:
MyApp.EAR
META-INF
lib
plugins
plugin1.JAR
app.WAR
logic1.JAR
logic2.JAR
for example: in the application.xml i have the references for app.WAR, logic1.JAR and logic2.JAR (they are always inside the system), at startup the application looks inside the folder "plugins" for any plugin (specific JARs) to be added to the system.
I hope i've been more clear about what i'm trying to do...
It seems that the EJB are not even registered in the JNDI tree of the server. Which application server are you using? You can have a look to this JNDI tree to see if the EJBs are there, but the way to do this depends on the specific server.
How are you declaring the JAR that contains the EJBs in the EAR application.xml?
It should be someting lide this:
<application>
....
<module>
<ejb>nameOfTheJarFile.jar</ejb>
</module>
</application>
The Jar should be in a the "/lib" directory of the EAR.
I hope this helps.

Inherit web.xml from jar file

We have many web applications that have shared setting (the web.xml and servlets are the same) and just Spring routes requests to different beans (BlazeDS & Spring).
My question is: is there a way to place web.xml in a shared jar? or another way to have the common web.xml exist once so it can come from a framework?
Servlet 3 specification support for web.xml includes.
Which means that you can split your giant configuration file to few smaller: spring-config.xml, blazeds-config.xml etc

Resources