Run code in Vaadin 8 application idependent of UI - vaadin

In earlier versions, you could have a class which implements ServletContextListener and put your code in the contextInitialized method, so that it runs when the server starts. This is useful for loading up the database into memory. How does one achieve this in a Vaadin 8 project?

In exactly the same way: By registering a ServletContextListener. You can use the #WebListener annotation for this. For example:
public class WebConfig {
#WebServlet("/*")
#VaadinServletConfiguration(ui = VaadinUI.class, productionMode = false)
public static class JdbcExampleVaadinServlet extends VaadinServlet {
}
#WebListener
public static class JdbcExampleContextListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
try {
DatabaseService.init();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
DatabaseService.shutdown();
}
}
}

Related

Vaadin 23 override internal error message

when an error occurs inside the application, the user sees the following message:
Is it possible to override it?
I aaded the following:
public class CustomErrorHandler implements ErrorHandler {
private static final Logger logger = LoggerFactory.getLogger(CustomErrorHandler.class);
#Override
public void error(ErrorEvent errorEvent) {
logger.error("Something wrong happened", errorEvent.getThrowable());
Notification.show("An internal error has occurred. Please contact support.");
if (UI.getCurrent() != null) {
UI.getCurrent().access(() -> {
Notification.show("An internal error has occurred. Please contact support.");
});
}
}
}
#Component
public class ServiceListener implements VaadinServiceInitListener {
private static final Logger logger = LoggerFactory.getLogger(LanguageReceiver.class);
#Override
public void serviceInit(ServiceInitEvent event) {
event.getSource().addSessionInitListener(
initEvent -> {
logger.info("A new Session has been initialized!");
VaadinSession.getCurrent().setErrorHandler(new CustomErrorHandler());
});
event.getSource().addUIInitListener(
initEvent -> logger.info("A new UI has been initialized!"));
}
}
#ParentLayout(MainLayout.class)
#AnonymousAllowed
public class ExceptionHandler extends VerticalLayout implements HasErrorParameter<Exception> {
static final Logger logger = LoggerFactory.getLogger(ExceptionHandler.class);
#Override
public int setErrorParameter(BeforeEnterEvent event, ErrorParameter<Exception> parameter) {
logger.error("Error", parameter.getException());
Label label = new Label(parameter.getException().getMessage());
add(label);
return HttpServletResponse.SC_NOT_FOUND;
}
}
but still unable to override the mentioned error on the screenshot above. Please show how to do this.
Generally, you need to extend SystemMessages and override getInternalErrorMessage().
Then you can register it using:
YourSystemMessages sysMessages = new YourSystemMessages();
VaadinService.getCurrent().setSystemMessagesProvider(systemMessagesInfo -> sysMessages);
and if you want to reset it to the default one:
VaadinService.getCurrent().setSystemMessagesProvider(DefaultSystemMessagesProvider.get());
In a Spring Boot based application you can register it in any implementation of VaadinServiceInitListener such as:
#Component
public class CustomSystemMessagesInitializer implements VaadinServiceInitListener {
#Autowired
private YourSystemMessages sysMessages;
// You can provide your SystemMessages instance in any way that suits you.
#Override
public void serviceInit(ServiceInitEvent serviceInitEvent) {
serviceInitEvent.getSource()
.setSystemMessagesProvider(systemMessagesInfo -> sysMessages);
}
}
Note that serviceInitEvent.getSource() returns the VaadinService instance, so it can be used as the reference as an alternative to VaadinService.getCurrent.

Getting TypeLiterals via method to reduce verbosity

I want to reduce the verbosity of binding a generic interface to several implementations based on TypeLiterals...
I have an interface FieldComputer<T extends ComputeField> where ComputeField is my model interface.
Tried extending a ShortLiteral class (see example below) to reduce the verbosity but it doesn't seem to work. would like to understand why?
// A typical Guice Module
public class ConflationModule implements Module {
// typical overridden configure method
public void configure(Binder binder) {
// Works but is verbose....
bindField_1(binder,
new TypeLiteral<FieldComputer<ComputeFieldImpl>>(){},
FieldComputerImpl.class);
// Doesn't Work
bindField_1(binder,
new ShortLiteral<ComputeFieldImpl>(){},
FieldComputerImpl.class);
// Doesn't Work
bindField_2(binder,
new ShortLiteral<ComputeFieldImpl>(){},
FieldComputerImpl.class);
}
private static class ShortLiteral<CF extends ComputeField> extends TypeLiteral<FieldComputer<CF>>{}
private <CF extends ComputeField> void bindField_1(Binder binder,
TypeLiteral<FieldComputer<CF>> typeLiteral,
Class<? extends FieldComputer<CF>> clazz
) {
binder.bind(typeLiteral).to(clazz);
}
private <CF extends ComputeField> void bindField_2(Binder binder,
ShortLiteral<CF> typeLiteral,
Class<? extends FieldComputer<CF>> clazz
) {
binder.bind(typeLiteral).to(clazz);
}
}
I would suggest you just create TypeLiteral programmatically, here is an example how to do it with different implementations of one interface:
class TypeLiteralModule extends AbstractModule {
#Override
protected void configure() {
customBind(String.class, StringConsumer.class);
customBind(Integer.class, IntegerConsumer.class);
}
private <T> void customBind(Class<T> clazz, Class<? extends Consumer<T>> impl) {
var typeLiteral = (TypeLiteral<Consumer<T>>) TypeLiteral.get(Types.newParameterizedType(Consumer.class, clazz));
bind(impl).in(Singleton.class);
bind(typeLiteral).to(impl);
}
}
class StringConsumer implements Consumer<String> {
#Override
public void accept(String s) {
}
}
class IntegerConsumer implements Consumer<Integer> {
#Override
public void accept(Integer s) {
}
}

Inject dependencies into ServletContextListener using HK2 in Jersey

In order to initialize the application at startup, I extended ServletContextListener:
#WebListener
public class MyServletContextListener implements javax.servlet.ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
... initialization code here
}
#Override
public void contextDestroyed(ServletContextEvent sce) {}
}
Now I want to extract the initialization logic into a standalone StartupManager class, and delegate to this class from MyServletContextListener:
public class StartupManager {
public void performStartup() {
... initialization code here
}
}
I tried to inject StartupManager into ServletContextListener by simply adding #Inject annotation:
#WebListener
public class MyServletContextListener implements javax.servlet.ServletContextListener {
#Inject StartupManager mStartupManager;
#Override
public void contextInitialized(ServletContextEvent sce) {
mStartupManager.performStartup();
}
#Override
public void contextDestroyed(ServletContextEvent sce) {}
}
This did not work - the reference is null when contextInitialized(ServletContextEvent ) is called.
Then I thought that I might have to register a binder:
#ApplicationPath("")
public class MyResourceConfig extends ResourceConfig {
public MyResourceConfig() {
register(new DependencyInjectionBinder());
}
}
public class DependencyInjectionBinder extends AbstractBinder {
#Override
protected void configure() {
bind(StartupManager.class).to(StartupManager.class);
}
}
This did not work either.
My question is how can I perform injection of dependencies into ServletContextListener? Preferably constructor injection, but field injection will also be alright.
It's not going to work, as the servlet listener and Jersey are not linked to the same system. As an alternative, you can use Jersey's Event Listeners. You can implement an ApplicationEventListener where you would be able to initialization and clean up in the same way you would in the servlet listener. You would be able to inject your services into Jersey's listener.

Jedis Cache implementation without JedisPool/commons-pool2-2.0

How to implement Jedis without JedisPool/commons-pool2-2.0 because still we are using jdk 1.5(commons-pool2-2.0 does not support JDK 1.5)
How to implement a thread-safe connection pooling?
I'm not sure about Jedis compatibility with Java 5. You can create your own pooling based on the older commons-pool 1.6 library. You do not need to have commons-pool2 on your class path to run jedis. I used Jedis 2.7.3 and commons-pool 1.6 to validate the solution approach.
Find the example code attached:
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
import redis.clients.jedis.Jedis;
public class JedisWithOwnPooling {
public static void main(String[] args) throws Exception {
ObjectPool<Jedis> pool = new GenericObjectPool(new JedisFactory("localhost"));
Jedis j = pool.borrowObject();
System.out.println(j.ping());
pool.returnObject(j);
pool.close();
}
private static class JedisFactory implements PoolableObjectFactory<Jedis> {
private String host;
/**
* Add fields as you need. That's only an example.
*/
public JedisFactory(String host) {
this.host = host;
}
#Override
public Jedis makeObject() throws Exception {
return new Jedis(host);
}
#Override
public void destroyObject(Jedis jedis) throws Exception {
jedis.close();
}
#Override
public boolean validateObject(Jedis jedis) {
return jedis.isConnected();
}
#Override
public void activateObject(Jedis jedis) throws Exception {
if (!jedis.isConnected()) {
jedis.connect();
}
}
#Override
public void passivateObject(Jedis jedis) throws Exception {
}
}
}

How Google Guice is working without #Inject anywhere in my test program?

I started exploring Google Guice today to do dependency injection in my application.
I noticed I am not using #Inject annotation anywhere. But it's working. Can not understand this concept. In this example, where #Inject is the best fit in my scenerio? If any one can point me out.
public interface Tweeter {
public void sendTweet(String message);
}
public class SmsTweeter implements Tweeter {
#Override
public void sendTweet(String message) {
System.out.println("You SMS tweet: "+message);
}
}
import com.google.inject.AbstractModule;
public class TweetModule extends AbstractModule{
#Override
protected void configure() {
bind(Tweeter.class).to(SmsTweeter.class);
}
}
import com.google.inject.Guice;
import com.google.inject.Injector;
public class TestTweetClient {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TweetModule());
Tweeter tweeter = injector.getInstance(Tweeter.class);
tweeter.sendTweet("Hi there");
}
}
It prints (the hidden implementation works):
You SMS tweet: Hi there
There is no best fit for #Inject in your example. The class SmsTweeter has an implicit zero-args constructor. You could make it explicit and add #Inject there but it is not necessary.
public class SmsTweeter implements Tweeter {
#Inject
SmsTweeter() {
// nothing to do
}
#Override
public void sendTweet(String message) {
System.out.println("You SMS tweet: "+message);
}
}

Resources