Inject classloader to custom message interpolator to fetch resource bundles outside classpath - hibernate-validator

As part of internationalizing quarkus application, I placed resource bundle properties outside build classpath and now I need my custom resourcebundlemessage interpolator to look for bundles outside classpath by providing the classloader value. By default, message interpolator looks for classloader and since it is null, it is picking the default locale resource bundle. Could someone help me how should I inject classloader to custom message interpolator?

You probably want to use a custom ResourceBundleLocator:
public class MyResourceBundleLocator implements ResourceBundleLocator {
#Override
public ResourceBundle getResourceBundle(Locale locale) {
// Get the resource bundle from wherever you want.
// Note that resources are retrieved at runtime,
// so you can't access the source/build directories here.
return <your result>;
}
}
#ApplicationScoped
public class MyValidatorFactoryCustomizer implements ValidatorFactoryCustomizer {
#Override
public void customize(BaseHibernateValidatorConfiguration<?> configuration) {
configuration.messageInterpolator(new MyResourceBundleLocator());
}
}

Related

JAVAFx and Clean Architecture

I'm making an app that try to follow the Clean architecture guideline. The app use JavaFX as UI. JavaFX is make to use the MVC architecture. Is there a way to use both in conjunction like this?
My problem is i can't find a way to have a Controller and a Presenter that interact with the FXML file.
Currently i have this :
An FXML file that declare a controller with fx:controller attribute
A controller That handle event and called a usecase
A usecase like this:
public class SomeUseCase implements UseCase<Observable<String>> {
private SomeRepository repository;
public SomeUseCase(SomeRepository repository) {
repository = repository;
}
#Override
public void execute(Request request, Presenter presenter) {
SomeUseCaseRequest req = (SomeUseCaseRequest) request;
// I skip mapper that translate from request to entity and entity to repository
// And vice-versa for the respponse for clarity
presenter.render(this.repository.fetch(req.someParam));
}
}

Using a custom interceptor in spring-boot, the #Value default is taking precedence over my configured value

I am in the trenches of writing my first spring-boot app, so I believe I have a configuration issue somewhere that is causing my error.
I have a class, "MyInterceptor", and it is annotated with "#Component" and extending HandlerInterceptorAdapter.
#Component
public class MyInterceptor extends HandlerInterceptorAdapter { ... }
And I have a configuration class "WebConfiguration" that is annotated with "#Configuration" (and is NOT annotated with "#EnableWebMvc").
I declare/inject my interceptor class in WebConfiguration like so:
#Resource
private MyInterceptor myInterceptor;
and then specify this class as an interceptor like so:
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor);
}
In MyInterceptor, I have a property declared for which I want to inject a value. I have it declared, with a default, like so:
#Value("${my.interceptor.property:default_value}")
private String myInterceptorProperty;
When I have the "default_value" declared in the #Value annotation as I do above, then that value is always used. The value declared in my application-dev.yml file is ignored.
When I remove the default value, then the value in my application-dev.yml is used.
It is my suspicion that the default value from the #Value annotation is being loaded AFTER the configured value and overriding it for some reason. But I can't figure out why or how to stop it.
Other services in my app that are using #Value annotations, but that are NOT declared/injected in my WebConfiguration, are not exhibiting the same behavior.
I tried adding my interceptor like this instead:
#Bean
public MyInterceptor getMyInterceptor() {
return new MyInterceptor();
}
and then changed this:
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(getMyInterceptor());
}
But when I did this, then the configuration values in the application-dev.yml were never picked up regardless of whether or not I had a default value declared.
I do understand why the #Resource annotated injection is making my configured properties available, and why the direct constructor call in the Config class is not. But is using the #Resource annotation the wrong way to do it? Why isn't my default being overridden?
How should I be injecting configuration values into my interceptors and other classes that are similarly declared in my Config class?

Spring boot No WebApplicationContext found

I have a simple spring boot app and I'm trying to get it up and running. The config consists of an app context ( applicationContext.xml) XML with a bunch of beans in it. I have a Spring application class:
#SpringBootApplication
#Configuration
#ImportResource("classpath:applicationContext.xml")
public class WebCheckApplication {
private static final Logger logger = Logger.getLogger(WebCheckApplication.class);
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(WebCheckApplication.class, args);
if (logger.isDebugEnabled()) {
logger.debug("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
logger.debug(beanName);
}
}
}
}
And I have a #WebListener class that grabs a few beans from the WebContext from within the ServletContext:
#WebListener
public class SystemPropertiesContextInitializer extends SysPropsAlertsFetcher implements ServletContextListener {
private static final Logger logger = Logger.getLogger(SystemPropertiesContextInitializer.class);
#Override
public void contextDestroyed(ServletContextEvent sce) {
//remove the SystemProperties and alert types map object from context
sce.getServletContext().removeAttribute(BaseAuthenticatedController.SYSPROPS_KEY);
sce.getServletContext().removeAttribute(BaseAuthenticatedController.ALERT_TYPES_MAP_KEY);
}
#Override
public void contextInitialized(ServletContextEvent sce) {
SysPropsDataAccess = (SystemPropertiesDataAccess) WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext()).getBean("SystemPropertiesDataAccess");
AlertsDataAccess = (AlertDataAccess) WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext()).getBean("AlertsDataAccess");
fetchObjects(sce.getServletContext());
}
}
When I attempt to start the app, I get the following error:
SEVERE: Exception sending context initialized event to listener instance of class web.SystemPropertiesContextInitializer
java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
at org.springframework.web.context.support.WebApplicationContextUtils.getRequiredWebApplicationContext(WebApplicationContextUtils.java:83)
at .web.SystemPropertiesContextInitializer.contextInitialized(SystemPropertiesContextInitializer.java:31)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4994)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5492)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
and it occurs at this line:
SysPropsDataAccess = (SystemPropertiesDataAccess) WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext()).getBean("SystemPropertiesDataAccess");
It looks like Spring isn't creating a WebApplicationContext.
Greater than or equal 1.3.0.RC1 use #ServletComponentScan
#ServletComponentScan // <-- This scans for EJB #WebFilter, #WebListener and #WebServlet
#SpringBootApplication
#ImportResource("classpath:applicationContext.xml")
public class WebCheckApplication {
Less than or equal 1.2.x use #Component to scan for listener
#Component // <-- This allows the component to be found by #ComponentScan inside of #SpringBootApplication
#WebListener
public class MojoSystemPropertiesContextInitializer extends MojoSysPropsAlertsFetcher implements ServletContextListener {
War Deploy extend SpringBootServletInitializer
public class WebCheckApplication extends SpringBootServletInitializer {
In 1.3.0.RC1 #ServletComponentScan was added so simply annotating your main application config should allow these to be picked up. Otherwise adding #Component to your ServletContextListener should work
This link is a discussion on how they currently handle #WebFilter how they decided to handle #WebFilter and they also discuss SpringBootServletInitializer and how this would pick process each item twice if both were to be used. Also links to the commits that implement the new feature.
https://github.com/spring-projects/spring-boot/issues/2290
If you intend to deploy your application as a war file you may also have your main configuration extend SpringBootServletInitializer
http://docs.spring.io/spring-boot/docs/current/reference/html/howto-traditional-deployment.html
All that was needed was to make the Application class extend SpringBootServletInitializer

Configuring spring to return a static file on a Controller method

How do I say to Spring MVC to return a static resource at runtime(in a method)?
Explain better. I configured my application(spring-mvc 3.2.4) to deal with some static resource and to work with two view resolvers, FreeMaker and Json. I wish that in a controller method I would be able to say to spring-mvc that he must take the file in the static resource despite try hadle by one of views resolvers.
My configuration class looks like this:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.xxxx", excludeFilters = #Filter(Configuration.class)})
public class WebConfig extends WebMvcConfigurerAdapter {
...
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/app.js").addResourceLocations("/app.js");
}
...
#Bean
public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {
// Define the view resolvers
List<ViewResolver> resolvers = new ArrayList<ViewResolver>();
JsonViewResolver jsonViewResolver = new JsonViewResolver();
FreeMarkerViewResolver freeMarkerViewResolver = new FreeMarkerViewResolver();
freeMarkerViewResolver.setSuffix("rtl");
resolvers.add(jsonViewResolver);
resolvers.add(freeMarkerViewResolver);
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager(manager);
resolver.setViewResolvers(resolvers);
return resolver;
}
}
My controller:
#Controller
#RequestMapping("/")
public class JSViewController {
#RequestMapping(value="*.js")
public String resolveArquivo(HttpServletRequest request){
// Here I would be able to say to sprint to return a static resource instead of hadle it with one of the View Resolvers.
return request.getRequestURI().replace(request.getContextPath(),"");
}
}
Its would be better if you try to access static and dynamic data seperately as hitting a controller for static data will waste your resources, increase latency.
For eg. if you want to access js from jsp then you can use JSTL tag library which would dynamically return the output directory from where you can fetch the static resource.
This gives you the flexibility to cache your static resources (Akamei or something else) or server them from apache instead of tomcat.
If you really want to render your static resource from controller then you need to have an interceptor which could be called before any of the view resolvers which will identify whether the requested resource us static and render accordingly. But this would be invoked for every htttp request which is not desirable.
Unfortunately I wasn't able to figure out how return a static resource in runtime with spring, but I resolved the situation using the old and good Filter.

GWT css include with Client Bundle -> "No source code is available for type de.main.resources.ResourceBundle..."

after running into some problems with the deprecated ways to include css resources into my application I'm eager about using ClientBundle to include the css files.
I added the following line to my ###.gwt.xml file:
<inherits name="com.google.gwt.resources.Resources" />
I created an interface which looks like this:
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
public interface ResourceBundle extends ClientBundle
{
public static final ResourceBundle INSTANCE = GWT.create(ResourceBundle.class);
#Source("GWT_Chat.css")
public CssResource css();
}
In my onModuleLoad() method I'm calling:
Window.alert(ResourceBundle.INSTANCE.css().getText());
My css file is a random css file without any of the possible gwt additions.
When calling the application in the browser, the error I face is:
[ERROR] [gwt_chat] - Line 33: No source code is available for type de.main.resources.ResourceBundle;
did you forget to inherit a required module?
Is there anything I left out?
Yes, you need to implement a Subtype of CssResource and return it:
public interface ResourceBundle extends ClientBundle
{
public static final ResourceBundle INSTANCE = GWT.create(ResourceBundle.class);
#Source("GWT_Chat.css")
public MyCssResource css();
public static interface MyCssResource extends CssResource {
String getText();
}
}

Resources