IllegalStateException: No suitable methods for action

I founded two examples of using actions - https://doc.cuba-platform.com/manual-6.3/declarative_actions.html

  1. Declaring actions at the screen level:

XML-descriptor of my screen:

    <window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
            caption="msg://browseCaption"
            class="com.client.web.item.CardItemBrowse"
            focusComponent="documentsTable"
            lookupComponent="documentsTable"
            messagesPack="com.client.web.item">
    		<dsContext>
    			<collectionDatasource id="cardItemDs" class="com.client.entity.CardItem" view="_local">
    				<query>
    					<![CDATA[select c from demo$CardItem c]]>
    				</query>
    			</collectionDatasource>
    		</dsContext>
    	
    	    <actions>
    	        <action id="helloAction" caption="Say hello" invoke="sayHello"/>
    	        <action id="goodbyeAction" caption="Say goodbye" invoke="sayGoodbye"/>
    	    </actions>
        
            <layout expand="documentsTable" spacing="true">
            	<button action="helloAction"/>
            	<filter id="filter" applyTo="documentsTable" datasource="cardItemDs">
                	<properties include=".*"/>
            	</filter>
            	<table id="documentsTable" width="100%">
    				<columns>
                    	<column id="cardOutcomeNumber"/>
    					<column id="cardDeliveryMethod"/>
    				</columns>
     				<rows datasource="cardItemDs"/>
                	<rowsCount/>
    			</table>        	
    		</layout>
    </window>

Controller:

    public class CardItemBrowse extends AbstractLookup {
        @Inject
        private CollectionDatasource<CardItem, UUID> cardItemDs;
    	
        @Inject
        private CardItemService cardItemService;
        
        @Named("documentsTable")
        private Table documentsTable;

    	@Override
        public void init(Map<String, Object> params) {
    		super.init(params);
    		
    		List<CardItemVO> cardItems = cardItemService.loadCardItems();

    		documentsTable.setColumnCaption("cardOutcomeNumber", "cardOutcomeNumber");
    		documentsTable.setColumnCaption("cardDeliveryMethod", "cardDeliveryMethod");

    		documentsTable.setWidth("100%");
    		documentsTable.setHeight("200px");
    		
    		documentsTable.setDatasource(cardItemDs);
    		documentsTable.setVisible(true);
    	}
    	
    	public void sayHello(Component component) {
    	    showNotification("Hello!", NotificationType.TRAY);
    	}
    	
    	public void sayGoodbye(Component component) {
    	    showNotification("Goodbye!", NotificationType.TRAY);
    	}
    }

When I try to call these actions, I get the following:

java.lang.IllegalStateException: No suitable methods named sayHello for action helloAction
	at com.haulmont.cuba.gui.xml.DeclarativeAction.actionPerform(DeclarativeAction.java:97)
	at com.haulmont.cuba.web.gui.components.WebButton.performAction(WebButton.java:44)
	at com.haulmont.cuba.web.gui.components.WebButton.lambda$new$61446b05$1(WebButton.java:36)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:510)
	at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:200)
	at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:163)
	at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:1037)
	at com.vaadin.ui.Button.fireClick(Button.java:377)
	at com.haulmont.cuba.web.toolkit.ui.CubaButton.fireClick(CubaButton.java:54)
	at com.vaadin.ui.Button$1.click(Button.java:54)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:158)
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:119)
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocation(ServerRpcHandler.java:444)
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:409)
	at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:274)
	at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:90)
	at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
	at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1435)
	at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:361)
	at com.haulmont.cuba.web.sys.CubaApplicationServlet.serviceAppRequest(CubaApplicationServlet.java:300)
	at com.haulmont.cuba.web.sys.CubaApplicationServlet.service(CubaApplicationServlet.java:191)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:107)
	at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:73)
	at com.haulmont.cuba.web.sys.CubaHttpFilter.doFilter(CubaHttpFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)
  1. Declaring actions for PopupButton:

    XML-descriptor of my screen:

    	// SKIPPED
        </dsContext>
            <layout expand="documentsTable" spacing="true">
     			<hbox id="fieldsBox" spacing="true">
    			<popupButton caption="Say something">
    			    <actions>
    			        <action id="helloAction" caption="Say hello" invoke="sayHello"/>
    			        <action id="goodbyeAction" caption="Say goodbye" invoke="sayGoodbye"/>
    			    </actions>
    			</popupButton> 			
            	</hbox>        
            	<filter id="filter" applyTo="documentsTable" datasource="cardItemDs">
    			// SKIPPED

The controller is the same.

What could be the problem?

I would be very grateful for the information. Thanks to all.

Hi,

Did you either hot deploy your changes or restart the app?

Regards,
Gleb

Hi, Gleb!

Yes, I tried both options.

I also deleted the contents of the work and the temp folders.

Not yet helped…

Regards,
Aleksey

In this case, could you please attach a sample project in which the problem is reproduced?

No problem.

Note, that in CardItemEdit all works perfectly.

Unfortunately, can’t attach file here.

In short.

CardItemEdit:

public class CardItemEdit extends AbstractEditor<CardItem> {

	@Inject
    private Datasource<CardItem> cardItemDs;

	@Named("cardItemsGroup.cardCreationDate")
    private Field cardCreationDate;
    
	@Inject
    private LookupField cardType;
    @Inject
    private LookupField cardSubType;
    
    @Named("cardItemsGroup.cardOutcomeNumber")
    private Field cardOutcomeNumber;
    @Named("cardItemsGroup.cardDate")
    private Field cardDate;
    @Named("cardItemsGroup.cardOrganization")
    private Field cardOrganization;
    @Named("cardItemsGroup.cardDeliveryMethod")
    private Field cardDeliveryMethod;
    @Named("cardItemsGroup.cardAdditionalInformation")
    private Field cardAdditionalInformation;
    @Named("cardItemsGroup.registratorName")
    private Field registratorName;

    @Inject
    private CardItemService cardItemService;
    
    public void onCreateBtnClick(Component source) {
    	com.client.vo.CardItem cardItemVO = 
    			new com.client.vo.CardItem();
    	
    	com.client.vo.CardType cardTypeVO = 
    			new com.client.vo.CardType();
    	com.client.vo.CardSubType cardSubTypeVO = 
    			new com.client.vo.CardSubType();

    	com.client.entity.CardType cardTypePO = cardType.getValue();
    	com.client.entity.CardSubType cardSubTypePO = cardSubType.getValue();
    	
    	cardTypeVO.setA(cardTypePO.getA());
    	cardTypeVO.setB(cardTypePO.getB());
    	
    	cardSubTypeVO.setA(cardSubTypePO.getA());
    	cardSubTypeVO.setB(cardSubTypePO.getB());
    	cardSubTypeVO.setCardType(cardTypeVO);
    	
    	cardItemVO.setCardType(cardTypeVO);
    	cardItemVO.setCardSubType(cardSubTypeVO);
    	cardItemVO.setCardOutcomeNumber(cardOutcomeNumber.getValue());
    	cardItemVO.setCardOrganization(cardOrganization.getValue());
    	cardItemVO.setCardDeliveryMethod(cardDeliveryMethod.getValue());
    	cardItemVO.setCardDate(cardDate.getValue());
    	cardItemVO.setCardCreationDate(cardCreationDate.getValue());
    	cardItemVO.setCardAdditionalInformation(cardAdditionalInformation.getValue());
    	cardItemVO.setRegistratorName(registratorName.getValue());
    	
    	cardItemService.saveCardItem(cardItemVO);
        cardItemDs.refresh();
    }
}

card-item-edit.xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
        caption="msg://editCaption"
        class="com.client.web.item.CardItemEdit"
        datasource="cardItemDs"
        focusComponent="cardItemsGroup"
        lookupComponent="cardItemsGroup"
        messagesPack="com.client.web.item">
    
     <dsContext>
        <datasource id="cardItemDs" class="com.client.entity.CardItem" view="_local"/>
        	<collectionDatasource id="cardTypeDs" class="com.client.entity.CardType">
            <query>
                <![CDATA[select e from demo$CardType e]]>
            </query>
        </collectionDatasource>
        	<collectionDatasource id="cardSubTypeDs" class="com.client.entity.CardSubType">
            <query>
                <![CDATA[select s from demo$CardSubType s where s.cardType.id = :ds$cardTypeDs]]>
            </query>
        </collectionDatasource>
    </dsContext>
    
    <dialogMode forceDialog="true" width="AUTO"/>
	<layout spacing="true">
        <fieldGroup id="cardItemsGroup" datasource="cardItemDs">
            <column width="500px">
                <field id="cardCreationDate" property="cardCreationDate" editable="false" datasource="cardItemDs" />
                <field id="cardTypeField" caption="Тип документа">
            		<lookupPickerField id="cardType" datasource="cardItemDs" property="cardType" optionsDatasource="cardTypeDs"/>
				</field>
                <field id="cardSubTypeField" caption="Подтип документа">
                	<lookupPickerField id="cardSubType" datasource="cardItemDs" property="cardSubType" optionsDatasource="cardSubTypeDs"/>
				</field>
                <field id="cardOutcomeNumber" datasource="cardItemDs" property="cardOutcomeNumber"/>
                <field id="cardDate" datasource="cardItemDs" property="cardDate"/>
                <field id="cardOrganization" datasource="cardItemDs" property="cardOrganization"/>
                <field id="cardDeliveryMethod" datasource="cardItemDs" property="cardDeliveryMethod"/>
                <field id="cardAdditionalInformation" datasource="cardItemDs" property="cardAdditionalInformation"/>
                <field id="registratorName" datasource="cardItemDs" property="registratorName"/>
            </column>
        </fieldGroup>
        <buttonsPanel id="cieButtonsPanel" alwaysVisible="true">
			<button id="createBtn" caption="documentsTable.create" invoke="onCreateBtnClick"/>
			<button id="removeBtn" caption="documentsTable.remove" invoke="onRemoveBtnClick"/>
        </buttonsPanel>
    </layout>
</window>

CardItemBrowse:

package com.client.web.item;

import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.inject.Inject;
import javax.inject.Named;

import com.haulmont.cuba.core.entity.Entity;
import com.haulmont.cuba.gui.WindowManager;
import com.haulmont.cuba.gui.components.AbstractLookup;
import com.haulmont.cuba.gui.components.Button;
import com.haulmont.cuba.gui.components.Table;
import com.haulmont.cuba.gui.components.actions.CreateAction;
import com.haulmont.cuba.gui.data.CollectionDatasource;
import com.haulmont.cuba.gui.data.Datasource;
import com.haulmont.cuba.gui.data.DsBuilder;
import com.haulmont.cuba.gui.xml.layout.ComponentsFactory;
import com.client.entity.CardItem;
import com.client.service.CardItemService;
import com.vaadin.ui.Component;
import com.vaadin.ui.Layout;


public class CardItemBrowse extends AbstractLookup {
    @Inject
    private CollectionDatasource<CardItem, UUID> cardItemDs;
	
    @Inject
    private CardItemService cardItemService;
    
    @Named("documentsTable")
    private Table documentsTable;
    

	@Override
    public void init(Map<String, Object> params) {
		List<com.client.vo.CardItem> cardItems =
				cardItemService.loadCardItems();

		documentsTable.setColumnCaption("cardOutcomeNumber", "cardOutcomeNumber");
		documentsTable.setColumnCaption("cardDeliveryMethod", "cardDeliveryMethod");

		documentsTable.setWidth("100%");
		documentsTable.setHeight("200px");
		
		documentsTable.setDatasource(cardItemDs);
		documentsTable.setVisible(true);
		
	}
	
	public void sayHello(Component component) {
	    showNotification("Hello!", NotificationType.TRAY);
	}
	
	public void sayGoodbye(Component component) {
	    showNotification("Goodbye!", NotificationType.TRAY);
	}
	
	public void onCreateBtnClick(Component source) {
		showNotification("Create!", NotificationType.TRAY);
	}
	
	public void onRemoveBtnClick(Component source) {
		showNotification("Remove!", NotificationType.TRAY);
	}
	
	
//    public void loadEditorAction(Component source) {
//		showNotification("Select a customer", NotificationType.HUMANIZED);
//		 openWindow("demo$CardItem.edit", 
//				 WindowManager.OpenType.DIALOG.width(800).height(300).closeable(true).resizable(true).modal(false));		
//    }	
//	
//	public void onCreateButtonClick(Component source) {
//		showNotification("Select a customer", NotificationType.HUMANIZED);
//		 openWindow("demo$CardItem.edit", 
//				 WindowManager.OpenType.DIALOG.width(800).height(300).closeable(true).resizable(true).modal(false));		
//	}
}

card-item-browse:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
        caption="msg://browseCaption"
        class="com.client.web.item.CardItemBrowse"
        focusComponent="documentsTable"
        lookupComponent="documentsTable"
        messagesPack="com.client.web.item">
    <dsContext>
        <collectionDatasource id="cardItemDs" class="com.client.entity.CardItem" view="_local">
            <query>
                <![CDATA[select c from demo$CardItem c]]>
            </query>
        </collectionDatasource>
    </dsContext>
        <layout expand="documentsTable" spacing="true">
 			<hbox id="fieldsBox" spacing="true">

        <buttonsPanel id="cieButtonsPanel" alwaysVisible="true">
			<button id="createBtn" caption="documentsTable.create" invoke="onCreateBtnClick"/>
			<button id="removeBtn" caption="documentsTable.remove" invoke="onRemoveBtnClick"/>
        </buttonsPanel>
 			
			<popupButton caption="Say something">
			    <actions>
			        <action id="helloAction" caption="Say hello" invoke="sayHello"/>
			        <action id="goodbyeAction" caption="Say goodbye" invoke="sayGoodbye"/>
			    </actions>
			</popupButton> 			
        	</hbox>        
        	<filter id="filter" applyTo="documentsTable" datasource="cardItemDs">
            	<properties include=".*"/>
        	</filter>
        	<table id="documentsTable" width="100%">
				<columns>
                	<column id="cardOutcomeNumber"/>
					<column id="cardDeliveryMethod"/>
				</columns>
 				<rows datasource="cardItemDs"/>
            	<rowsCount/>
			</table>        	
		</layout>
</window>

The problem with card-item-browse.xml and CardItemBrowse controller.

What CUBA Platform version do you use?

1 Like

I use Cuba Version 6.8.5
Built on 2018-04-26 17:19:18

As far as I understood, in this version it is impossible?

I think the reason is in the parameter of methods - Component component
I’ll try to delete it and I’ll show what happened.

Yes, it works:

public void someMethod() {
   showNotification("Hello!", NotificationType.TRAY);
}

According with this documentation: https://doc.cuba-platform.com/manual-6.8/gui_Button.html

1 Like