lunes, 12 de octubre de 2020

35. Migrating to Vaadin version 17 & 18. Problems in annotaitons: @Push and @Theme

see: Vaadin Forum

1.VaadinServlet/CdiVaadinServlet implementions

In version 14

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package openadmin.listeners;

import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;

import com.vaadin.cdi.CdiVaadinServlet;
import com.vaadin.flow.server.Constants;
//import com.vaadin.flow.server.VaadinServlet;


/**
 * Information about app servlet 
 * 
 * Necessary for defining i18n Provider
 * @author ximo 
 *
 */
@SuppressWarnings("serial")
@WebServlet(
	urlPatterns = "/*", 
	name = "slot", 
	asyncSupported = true, //For @Push
	
	
	initParams = {
		// I18N Provider for translation of labels	
        //Vaadin 14,15,16
	@WebInitParam(name = Constants.I18N_PROVIDER, value = "openadmin.i18n.MyI18nProvider"),	
	// Enable pmpm instead of npm	2020-05-27 for Vaadin 15 
	// @see https://dantesquevaadin.blogspot.com/2020/05/32-vaadin-15-new-version-using-pnpm.html
	@WebInitParam(name = "pnpm.enable", value = "true")
	})

// Deprecated. @see https://vaadin.com/docs/v14/flow/production/tutorial-production-mode-basic.html
//@VaadinServletConfiguration(productionMode = false)

//public class ApplicationServlet extends VaadinServlet {
public class ApplicationServlet extends CdiVaadinServlet {
}


now in version 17, there are several changes


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package openadmin.listeners;

import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;

import com.vaadin.cdi.CdiVaadinServlet;
//import com.vaadin.flow.server.VaadinServlet;
import com.vaadin.flow.server.InitParameters;

/**
 * Information about app servlet 
 * 
 * Necessary for defining i18n Provider
 * @author ximo 
 *
 */
@SuppressWarnings("serial")
@WebServlet(
	urlPatterns = "/*", 
	name = "slot", 
	asyncSupported = true, //For @Push
	
	//pushmode = "manual",
	
	initParams = {
		//Vaadin 17
		// I18N Provider for translation of labels	
     		@WebInitParam(name = InitParameters.I18N_PROVIDER, value = "openadmin.i18n.MyI18nProvider"),
        	@WebInitParam(name = InitParameters.SERVLET_PARAMETER_PUSH_MODE, value= "PushMode.MANUAL" ),
        	@WebInitParam(name = InitParameters.SERVLET_PARAMETER_ENABLE_PNPM, value= "true" ),
        	//End Vaadin17
	})

//public class ApplicationServlet extends VaadinServlet {
public class ApplicationServlet extends CdiVaadinServlet {
}


2.VaadinServiceInitListener implementions and @Push

In version 14, the @Push annotation was placed  in the main form, now in version 17 gives a runtime error: 

Found app shell configuration annotations in non `AppShellConfigurator` classes.

Please create a custom class implementing `AppShellConfigurator` and move the following annotations to it:

    - @Push from openadmin.ui.forms.MainView

So, the class implementing VaadinServiceInitListener should now implement also the AppShellConfigurator interface and will contain the @Push annotation

Now let's see the new class with the old version aspects commented


In version 18 also complains about the @Theme annotation and does not want it in the main form



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package openadmin.listeners;


import com.vaadin.flow.component.page.AppShellConfigurator;
import com.vaadin.flow.component.page.Push;
import com.vaadin.flow.server.ServiceInitEvent;
import com.vaadin.flow.server.VaadinServiceInitListener;
import com.vaadin.flow.shared.communication.PushMode;

import openadmin.ui.forms.LoginForm;
import openadmin.vaadin.http.SessionParams;
import openadmin.vaadin.http.VaadinHttpUtils;



/**
 * This class is used to listen to BeforeEnter event of all UIs in order to
 * check whether a user is signed in or not before allowing entering any page.
 * It is registered in a file named
 * com.vaadin.flow.server.VaadinServiceInitListener in META-INF/services.
 * 
 * NOTE that a SessionScopped object cannot be injected so, to know if the user is logged in
 *   we need to make use of information stored in the Session object with keys "CURRENT_USER" 
 */




@SuppressWarnings("serial")
//Vaadin14,15,16
//public class LoggedInListener implements VaadinServiceInitListener {

//Only Vaadin 17
@Push(PushMode.MANUAL)

//Only for Vaadin 18 +
@Theme(value = Lumo.class)

public class LoggedInListener implements VaadinServiceInitListener, AppShellConfigurator {
	. . . . . . . . 

remember to remove the@Push and @Theme annotations from the main form!!!!

jueves, 1 de octubre de 2020

34. Understanding ui.access(). @Push annotation

 0. Introduction

I want to show only a few remarks about "Asynchronous Updates" from Vaadin tutorial.

When you run a thread,  the Session seems to be not accessible, so the UI. You should take it into account as when manipulating form components from the thread!!!


1. Hanging the execution

Be very careful as the execution may hang in these cases:

  • When using the annotation @Push without options and the process is executed for the first time. Maybe I am doing something wrong but I don't know.
  • When using the annotation @Push( (PushMode.MANUAL) and not using ui.push() as the final sentence inside a ui.access()(() -> {...}) block; to assure the UI is updated
  • When using ui.push(), my advice is to put it into a try-catch block!
  • In Vaadin-14 use the @Push annotation in the main form, but in Vaadin-17 use it in the class that implements AppshellConfigurator. As it is explained in the next post.

ui.access(() -> {
  Span sp=new Span("Begin command...");
  view.add(sp);
  try {ui.push()} catch (Exception e){e.printstacktrace()}; //Last sentence 
});


2. Creating components dynamically from a thread

Components should be created within the ui.access() {} block, as you cannot access the Session or the UI outside this block. 

For instance, you cannot create an Anchor component outside this block as the creation implies access to the UI for getting URIs!!

In case you can create the component, you cannot attach it to the UI outside this block!