Jetty spring profile programmatically - spring

I'm looking for a way to set spring profile in jetty programmatically so that the application that the war file on the server used the given profile, this is my code:
final WebAppContext context = new WebAppContext();
context.setLogUrlOnStart(true);
context.setWar("target/deployables/myapp-rest/myapp-rest.war");
context.setContextPath("/" + TEST_APP_CONTEXT);
context.setParentLoaderPriority(true);
server.setHandler(context);
server.start();
I tried a couple of things but none of them seem to work... I need to pass -Dspring.profiles.active=myProfile

This is tested with Jetty 9.3 but webdefault.xml seem to also be available for lower versions (it's placement might be different though).
Go to $JETTY_HOME/etc and open webdefault.xml. Search for context-param in the file. Add this code somewhere below:
<context-param>
<param-name>spring.profiles.default</param-name>
<param-value>prod</param-value>
</context-param>
This will work if your web.xml (in the your-app.war file) doesn't contain this context-param.
Otherwise you could also use override-web.xml (docs) but you would need to configure it in jetty-web.xml and jetty-web.xml must be bundled inside the war... So YMMV, but I didn't want to change my war and webdefault.xml is an easier solution for me.

Related

Spring Security tag lib not working with JSF

I want to use springboot with security and primefaces.
I have followed this article but with one little change, I don't want to use JoinFaces. Everything works fine except the spring sec taglib.
xmlns:sec="http://www.springframework.org/security/tags
Now I'm not sure how to configure servletContext so that the sec tags would work.
Here is GitHub repo for now its really simple project just to test the combination SB + SS + PF.
I had the same scenario before and I ended up adding springsecurity.taglib.xml in my project. You can copy the file content from here and then register it in your web.xml file as follow:
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/springsecurity.taglib.xml</param-value>
</context-param>

How to use an existing web.xml in my new grails 3 app?

According to the documentation here it says:
If you have a modified web.xml template then you will need to migrate this to Spring as Grails 3.x does not use a web.xml (although it is still possible to have on in src/main/webapp/WEB-INF/web.xml).
which I interpret to mean that if I'm incorporating a 3rd party proprietary library that has a web.xml, then I can put it in src/main/webapp/WEB-INF unaltered (along with everything else that they put in their tomcat webapp directory) and grails will load it. Is this interpretation correct? That's what seems to be implied by this answer.
I started a grails 3 app with the react profile (I tried the web profile too) and a webpage with calls their servlet. However, while an html file in webapp can be found, the servlet call itself is returning 404 and I can't figure out why. If I build a war file and deploy on a standalone tomcat, the servlet call works, but when I run like this:
./gradlew server:bootRun --debug
then it doesn't, and I don't see anything interesting printed to the console.
Is there some URL mapping I need to manipulate or something in application.yml?
In the web.xml, the servlet that's being called looks like this (this is a small piece of it, does it am):
<servlet>
<servlet-name>DataSourceLoader</servlet-name>
<servlet-class>com.isomorphic.servlet.DataSourceLoader</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DataSourceLoader</servlet-name>
<url-pattern>/isomorphic/DataSourceLoader</url-pattern>
</servlet-mapping>
I realize the alternative is to rewrite web.xml using Beans and put stuff in resources.groovy, but I'd prefer an approach that requires as little of my coding as possible.
[update]
I've been able to update my grails-app/conf/spring/resources.groovy with this:
import org.springframework.boot.web.servlet.ServletRegistrationBean
// Place your Spring DSL code here
beans = {
DataSourceLoader(ServletRegistrationBean) { bean ->
servlet = new com.isomorphic.servlet.DataSourceLoader()
urlMappings = ['/isomorphic/DataSourceLoader']
}
}
and it seems to be working... Nevertheless, I am still interested in ways to only use web.xml, if possible, which is my original question.
As part of an upgrade from Grails 2.x to Grails 3.3, I had been previously using web.xml to define 3rd party servlets.
The approach I took in order to make these servlets available(and load at startup) was through a custom class. So you can define a custom class, in src/java as such:
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
public class ServletRegistrations {
#Bean
public ServletRegistrationBean fileServlet(){
ServletRegistrationBean registration = new ServletRegistrationBean(new FileServlet(), "/files/*");
// to load add startup uncomment the line below
//registration.setLoadOnStartup(1);
// define init param
registration.addInitParameter("basePath","/WEB-INF/resources");
return registration;
}
}
So although you don't define everything in one XML file, you can still define all your servlets in this one single class, so it's not a big change and I now I've gone through this once, I prefer to be able to do the definitions in code rather than xml. Hope that helps!

Spring #Scheduled job - Get base application path

I have a Spring MVC application and in it I am running a periodic job using a class with method annotated as #Scheduled
In this method, I want to get the base application path i.e. http://localhost:8080/ or http://www.mywebsite.com/ based on whether this is my local system or production system.
How can I do this? I do not have access to HttpServletRequest because this is not a Controller class.
Any hints would be appreciated
In my opinion it is a good idea to use profiles and store properties like base application path in properties file - where each environment has its own property file: config_dev.properties, config_production.properties
Once they are there you can load them in job-like classes using Environment (described on SpringSource blog).
How to configure Tomcat and Spring to use profiles: Spring 3.1 profiles and Tomcat configuration
Put a myconfiguration.properties out of your application, to let the application know that whether its running locally or in production. And then in your method annotated as #Scheduled just read the Property file.
String configPath = System.getProperty("config.file.path");
File file = new File(configPath);
FileInputStream fileInput = new FileInputStream(file);
Properties properties = new Properties();
properties.load(fileInput);
And provide the agrument,
-Dconfig.file.path=/path/to/myconfiguration.properties
when running your application server (or container). This can be done by putting,
JAVA_OPTS="$JAVA_OPTS -Dconfig.file.path=/path/to/myconfiguration.properties"
at the beginning (roughly) of the script, which is used while running your application server.
For tomcat its catalina.sh
For Jboss AS its run.sh
For weblogic its setDomainEnv.sh
And After doing that start your server and deploy your application. Finally, your #Scheduled method should know the information it needs. As the property file is outside of the application, you can change the value of the property when you want without rebuilding the application or without even disturbing it!
just add this code in your web.xml
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>my.root.path</param-value>
</context-param>
and use it your code as a system properties

Set log4j file path param in execution time

In Spring I have slf4j with log4j to resolve logging.
I put relative path in log4j.xml configuration, but when i execute app in Netbeans Tomcat and independent Apache Tomcat, relative path is different, and I must change manually.
My idea is obtain context realpath from Spring Controller and set it in log4j configuration in execution time. But I dont know...
How can I change file path param of log4j from Spring Controller?
Two suggestions for you to try:
Add a WebAppRootListener to your web.xml - this will configure a system property pointing (default to webapp.root, but you can customize using a context-param - see the Javadocs link) to the root of your web application, which you can then use in the log4j.properties/xml file:
<listener>
<listener-class>org.springframework.web.util.WebAppRootListener<listener-class>
<listener>
<!-- log4.appender.File=${webapp.root}/logs/web-app.log -->
Or use the Log4jConfigListener in your web.xml (which ultimately delegates to a Log4jConfigurer) - this is similar to the above, but allows you to define a custom log4j configu file and also allows for your web application to monitor the log4j config file for changes made at runtime and automatically update your loggers:
<context-param>
<!-- Configure Log4J from the following config file location -->
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener<listener-class>
<listener>
I would also recommend you read the Javadocs for the above in detail - there are some gotchas with regards to deploying multiple webapps in Tomcat and sharing of system properties, but this can all be worked around (providing a custom key for each webapp, rather than the default ${webapp.root}

Component Scan not finding #Component's in a JAR in Tomcat webapp

I just filed a bug in the Spring bugsystem ( https://jira.springsource.org/browse/SPR-8551 ), but I am still unsure if I am missing something
I tracked down a problem with <context:component-scan/> to this statement.
Given the two following classes which are in the same JAR in WEB-INF/lib of a web application (The JAR file has the directory structure):
test/TheBean.java:
package test;
#Component
public class TheBean{
}
test/BeanSearcher.java:
package test;
public class BeanSearcher{
public void init(){
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.scan("test");
ctx.refresh();
TheBean b= ctx.getBean(TheBean.class);
// What is the value of b?
}
}
If I run new BeanSearcher().init() in a jUnit test case or other type of standalone application, b is getting assigned an instance of TheBean, but if I run it, say, in a JSP, ctx.getBean() is returning null.
So, am I doing something wrong or not taking something into account, is this just a bug...?
EDIT 8/8/2011: It seems to work good as I tried to simplify the problem, but still, when I try to make it work, in the initialization of OpenCms, it fails. Now I am trying to look for the differences between working versions and the one which doesn't work. (Classloader, ubication of the relevant classes in different JARs or directly in WEB-INF/classes, calls via reflection, etc.)
As I wrote in the comment, the solution is given by the answer here:
Spring Annotation-based controllers not working if it is inside jar file
When you export the jar file using the export utility in eclipse there
is a option called Add directory entries.
The obvious question is whether you have things like these in your web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/foo.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Without these, Spring won't actually load at all, let alone properly build beans…

Resources