Spring Boot 1.5.2 FreeMarker change from DEBUG mode to RETHROW mode - spring

How do I change the FreeMarker "DEBUG" mode to the "RETHROW" mode in Spring Boot 1.5.2. I'm getting the following message in my browser when an exception occurs:
FreeMarker template error (DEBUG mode; use RETHROW in production!)
I've tried adding the following property to application.properties file:
spring.freemarker.template_exception_handler=rethrow
according to the following site: http://blog.64p.org/entry/2016/03/24/175906
but that didn't work.
Edit:
I saw there is a class called FreeMarkerProperties that has a class definition like the following:
#ConfigurationProperties(prefix = "spring.freemarker")
public class FreeMarkerProperties extends AbstractTemplateViewResolverProperties {
I assume this class should be filled with all the properties that starts with "spring.freemarker"
It has a method called getSettings. I decided to see what is returns if I autowire FreeMarkerProperties into my CommandLineRunner.
I changed my class that implements CommandLineRunner to the following:
#Component
public class ApplicationLoader implements CommandLineRunner {
private static final Logger logger = LoggerFactory.getLogger(ApplicationLoader.class);
...
#Autowired
FreeMarkerProperties properties;
#Override
#Transactional
public void run(String... strings) throws Exception {
StringBuilder sb = new StringBuilder();
for (String option : strings) {
sb.append(" ").append(option);
}
sb = sb.length() == 0 ? sb.append("No Options Specified") : sb;
logger.info(String.format("WAR launched with following options: %s", sb.toString()));
logger.info("FREEMARKER PROPERTIES");
for(String path : properties.getTemplateLoaderPath()) {
logger.info(path);
}
for(String setting : properties.getSettings().keySet()) {
logger.info("Freemarker: " + setting);
}
Which output the following:
2017-03-22 09:58:19.257 INFO 6635 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-03-22 09:58:19.292 INFO 6635 --- [ main] com.example.ApplicationLoader : WAR launched with following options: No Options Specified
2017-03-22 09:58:19.292 INFO 6635 --- [ main] com.example.ApplicationLoader : FREEMARKER PROPERTIES
2017-03-22 09:58:19.292 INFO 6635 --- [ main] com.example.ApplicationLoader : classpath:/templates/
2017-03-22 09:58:19.852 INFO 6635 --- [ main] com.example.DemoApplication : Started DemoApplication in 11.67 seconds (JVM running for 12.339)
So it seems like the FreemarkerProperties's getSettings method returns an empty list of settings. My application.properties:
# Spring Boot configuration.
# Uncomment below line to enable mobile device detection.
#spring.mobile.devicedelegatingviewresolver.enabled: true
spring.metrics.export.delay-millis=10000
spring.datasource.url=jdbc:postgresql://localhost:5432/**COMMENTED OUT***
spring.datasource.username=*
spring.datasource.password=*
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.hibernate.ddl-auto=create
server.session.timeout=1800
spring.freemarker.template_exception_handler=rethrow
Am I doing something wrong here? Why is the settings not populated in the FreemarkerProperties class?

In your application.properties try using
spring.freemarker.settings.template_exception_handler=rethrow

In the Spring Boot Module of one of my apps I'm loading the Freemarker Properties file with a #PropertySource annotation.
#SpringBootApplication
#PropertySource("classpath:/standalone.properties")
public class MailLauncher {
public static void main(String[] args) {
ApplicationContext ctx = new
AnnotationConfigApplicationContext("com.nixmash.blog.mail",
"com.nixmash.blog.jpa");
MailDemo demo = ctx.getBean(MailDemo.class);
demo.init();
((ConfigurableApplicationContext) ctx).close();
}
}
I'm not extending AbstractTemplateViewResolverProperties but rather using a config Bean
#Bean
public FreeMarkerViewResolver freemarkerViewResolver() {
FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
resolver.setPrefix("");
resolver.setCache(false);
resolver.setOrder(3);
return resolver;
}
Here's the .properties file.
spring.freemarker.enabled=false
spring.freemarker.template-loader-path=classpath:/freemarker/
spring.freemarker.charset=UTF-8
spring.freemarker.cache=false
spring.freemarker.check-template-location=false
spring.freemarker.settings.locale=en_US
If your application includes multiple modules and application.properties files it could also be a matter of one module .properties file overriding your FreeMarker module .properties file. Renaming the FreeMarker module .properties file and using #PropertySource would expose the properties, in that case.

Related

#SpringBootTest constructor is running multiple times

I am trying to run below test case in Spring Boot.
:: Spring Boot :: (v2.3.1.RELEASE)
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
#SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = com.dineoutsafe.api.dosadmin.DOSAdminAPIApplication.class)
#ActiveProfiles("test")
public class POSTSessionTest {
public POSTSessionTest() {
System.out.println("Calling post construct");
}
#Test
public void testOne(){
assertThat(45,equalTo(30+15));
}
#Test
public void testTwo(){
assertThat(45,equalTo(30+15));
}
#Test
public void testThree(){
assertThat(45,equalTo(30+15));
}
#Test
public void testFour(){
assertThat(45,equalTo(30+15));
}
#Test
public void testFive(){
assertThat(45,equalTo(30+15));
}
}
And I noticed that the constructor is running multiple times. Actually it is running (no. of #Test -1) times.
In standard output
2020-06-21 16:00:26.668 INFO 93912 --- [ task-1] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2020-06-21 16:00:26.679 INFO 93912 --- [ task-1] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2020-06-21 16:00:27.025 INFO 93912 --- [ Test worker] DeferredRepositoryInitializationListener : Spring Data repositories initialized!
2020-06-21 16:00:27.034 INFO 93912 --- [ Test worker] c.d.a.d.i.session.POSTSessionTest : Started POSTSessionTest in 5.511 seconds (JVM running for 6.414)
Calling post construct
Calling post construct
Calling post construct
Calling post construct
Same behaviour I noticed for #PostConstruct.
Is it normal for #SpringBootTest?
This is the default behavior of JUnit5, you can change it by annotating the per-class lifecycle on the class: https://junit.org/junit5/docs/5.0.1/api/org/junit/jupiter/api/TestInstance.Lifecycle.html

running the application on controller

I'm still a beginner with spring boot, I'm using spring JPA to fetch the data from multiple tables in the same database and everything going fine, I used to run my application at the Main but here I have added a Controller class and running things there, then i used #Scheduled(fixedRate=7000) instead of creating an infinite loop to keep check the data from db and stay live, the application working fine but as far as at the running time application executed twice instead of once at the beginning before scheduling, a is there any idea about what happened here :
Mainclass :
#SpringBootApplication
#EnableScheduling
public class AccessingDataJpaApplication {
public static void main(String[] args) throws Exception{
SpringApplication.run(AccessingDataJpaApplication.class);
}
}
Controller class :
#Controller
#EnableScheduling
public class MainController {
private static final Logger logger = LoggerFactory.getLogger(MainController.class);
#Autowired
private CustomerRepository customerRepository;
#Autowired
private MessageRepository messageRepository;
private Set<String> camps = new HashSet<String>();
#Bean
#Scheduled(fixedRate=7000)
public void run(){
logger.info("Running");
if((customerRepository.findAllByStatusAndCampType(0, 1).size()) > 0 ){
for(Customer customer : customerRepository.findAll()){
System.out.println(customer.getCampCd());
camps.add(customer.getCampCd());
}
System.out.println("----------------------------------------");
for(MessageCampain messagecampain : messageRepository.findAllByCampCdIn(camps)) {
System.out.println(messagecampain.toString());
}
System.out.println("------------------------------------------");
for(String value : camps) {
System.out.println(value);
}
}
}
}
execution log :
[ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
[ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
[ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
[ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
[ main] c.e.accessingdatajpa.MainController : Running
[ main] o.s.s.c.ThreadPoolTaskScheduler : Initializing ExecutorService 'taskScheduler'
[ main] c.e.a.AccessingDataJpaApplication : Started AccessingDataJpaApplication in 5.467 seconds (JVM running for 6.242)
[ scheduling-1] c.e.accessingdatajpa.MainController : Running
[ scheduling-1] c.e.accessingdatajpa.MainController : Running
you can notice that at Running word
It is because you annotate the run() in MainController as #Bean , which will creates a lite mode bean called run. (Spring represents this bean as the type of NullBean internally)
So , the 1st call of 'Running' in the main thread is due to spring instantiate this run bean. The remaining calls of 'Running' in the scheduling-1 thread are due to the the effect of #Scheduled. So please remove #Bean from the run() as it does not have any points to create a null bean ...
#Scheduled(fixedRate=7000)
public void run(){
}

#PropertySource does not bind a String propety to enum automatically?

In our integration test using springboot 1.4, we used
#ConfigurationProperties(locations = "classpath:test.yml")
with the locations attribute. This was mapping a string property to enum automatically. But starting from springboot 1.5, the locations attribute is removed.
As a workaround, I'm using #PropertySource but this doesn't support yaml file. So, I'm using a factory class to convert the yaml to java.util.properites. But I'm facing issues, with string property not binding to enum automatically.
Is there any good solution for this?
You can map yaml file to config class
The relative path of application.yml file is /myApplication/src/main/resources/application.yml.
The Spring application takes the first profile as the default profile unless declared otherwise in the Spring application.
YAML FILE
spring:
profiles: test
name: test-YAML
environment: test
servers:
- www.abc.test.com
- www.xyz.test.com
---
spring:
profiles: prod
name: prod-YAML
environment: production
servers:
- www.abc.com
- www.xyz.com
Binding YAML to a Config Class
To load a set of related properties from a properties file, we will create a bean class:
Configuration
#EnableConfigurationProperties
#ConfigurationProperties
public class YAMLConfig {
private String name;
private String environment;
private List<String> servers = new ArrayList<>();
// standard getters and setters
}
The annotation used here are:
#Configuration marks the class as a source of bean definitions
#ConfigurationProperties binds and validates the external configurations to a configuration class
#EnableConfigurationProperties this annotation is used to enable #ConfigurationProperties annotated beans in the Spring application
USAGE:
#SpringBootApplication
public class MyApplication implements CommandLineRunner {
 
    #Autowired
    private YAMLConfig myConfig;
 
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(MyApplication.class);
        app.run();
    }
 
    public void run(String... args) throws Exception {
        System.out.println("using environment: " + myConfig.getEnvironment());
        System.out.println("name: " + myConfig.getName());
        System.out.println("servers: " + myConfig.getServers());
    }
}

Configuring Camel for Spring with MINA 2

I want to configure Camel for Spring with MINA 2.
I did the following configuration code:
#Configuration
public class SpringConfiguration {
public static final String THREADPOOL_ID = "poolId";
#Bean
CamelContextConfiguration contextConfiguration() {
return new CamelContextConfiguration() {
#Override
public void beforeApplicationStart(CamelContext context) {
context.addComponent("mina2", new Mina2Component());
}
#Override
public void afterApplicationStart(CamelContext arg0) {
}
};
}
}
But when I wrote the router code like below. But it is not working:
#Component
public class RouteConfiguration extends RouteBuilder {
#Value("${app.collectorStringInput}")
private String collectorStringInput;
#Value("${app.mapOutputQueue}")
private String mapOutputQueue;
private final SiemParserProcessor parserProcessor;
public RouteConfiguration(SiemParserProcessor parser) {
this.parserProcessor = parser;
}
#Override
public void configure() throws Exception {
from("mina2:udp://10.31.0.32:514?disconnectOnNoReply=false&sync=false").to("log:edu.accs.siem.collector?level=DEBUG");
}
}
However, I can see this lines in the log:
2018-06-30 11:37:14.270 INFO 480 --- [ restartedMain] o.a.camel.spring.SpringCamelContext : Route: route1 started and consuming from: mina2://udp://10.31.0.32:514?disconnectOnNoReply=false&sync=false
2018-06-30 11:37:14.270 INFO 480 --- [ restartedMain] o.a.camel.spring.SpringCamelContext : Total 1 routes, of which 1 are started
2018-06-30 11:37:14.271 INFO 480 --- [ restartedMain] o.a.camel.spring.SpringCamelContext : Apache Camel 2.21.1 (CamelContext: camel-1) started in 0.185 seconds
It is working without using Spring. So I guess there is some configuration issue.
Can anybody tell me what I am missing?
PS: I checked out netty, but it seems not working even when not using Spring.
I got it working.
Actually, this was processing,
But somehow the logging wasn't displaying.

#Value is always null

I have a situation where my attempt to use a #Value annotation results in the value being a null.
This is part of a large project and I'm not sure which parts of it are needed. I am using Java anotations (no xml file) and Spring boot.
#Configuration
#EnableAutoConfiguration
#EnableConfigurationProperties
#ComponentScan
public class RESTApplication {
public static void main(String[] args) {
SpringApplication.run(RESTApplication.class, args);
}
}
application.properties contains:
maxuploadfilesize=925000000
I did try to create a PropertySourcesPlaceholderConfigurer as some websites mentioned to do so.
#Configuration
public class AppConfig {
#Bean
public static PropertySourcesPlaceholderConfigurer properties() {
return new PropertySourcesPlaceholderConfigurer();
}
}
Here is the class attempting to use it:
#Component
public class MyClass {
#Value("${maxuploadfilesize}")
String maxFileUploadSize;
public String getMaxFileUploadSize() {
return maxFileUploadSize;
}
public void setMaxFileUploadSize(String maxFileUploadSize) {
this.maxFileUploadSize = maxFileUploadSize;
}
}
However at runtime, maxFileUploadSize is always null. Note the below debug comment where PropertySourcesPropertyResolver seemed to find its correct value within the application.properties file.
2015-06-10 13:50:20.906 DEBUG 21108 --- [ main] o.s.c.e.PropertySourcesPropertyResolver : Searching for key 'maxuploadfilesize' in [applicationConfig: [classpath:/application.properties]]
2015-06-10 13:50:20.906 DEBUG 21108 --- [ main] o.s.c.e.PropertySourcesPropertyResolver : Found key 'maxuploadfilesize' in [applicationConfig: [classpath:/application.properties]] with type [String] and value '925000000'
It looks like MyClass was not processed as SpringBean, which would mean, that the #Value-annotation was not processed.
You could check that with providing a default value, like #Value("${maxuploadfilesize:'100'}"). If the value is still null, then you know, that MyClass is not instantiated as a SpringBean.
Since it is annotated with #Component, you should be able to simply inject it with
#Autowired private MyClass myclass;

Resources