WorkItem icon files can be places in the same directory where *.wid file is created:
[
        [
            "name" : "MyConcatDefinitions",
            "displayName" : "MyConcatDefinitions",
            "category" : "myconcatworkitem",
            "description" : "",
            "defaultHandler": "mvel: new com.ibm.MyConcatWorkItemHandler()",  
            "parameters" : [
                        "FirstName" : new StringDataType(),
                        "LastName" : new StringDataType()
            ],
            "results" : [
                      "FullName" : new StringDataType()
            ],
            "icon" : "MyConcatDefinitions.png"
        ]
]
To create a custom workItemHandler, create a MyConcatWorkItemHandler class that extends org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler class.
import org.kie.kogito.internal.process.workitem.KogitoWorkItem;
import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler;
import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager;
import org.kie.kogito.internal.process.workitem.WorkItemTransition;
import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler;
import org.slf4j.LoggerFactory;
public class MyConcatWorkItemHandler extends DefaultKogitoWorkItemHandler {
    private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(MyConcatWorkItemHandler.class);
    @Override
    public 
Optional<WorkItemTransition> 
activateWorkItemHandler(KogitoWorkItemManager manager, 
KogitoWorkItemHandler handler, KogitoWorkItem workItem, 
WorkItemTransition transition) {
        for (String parameter : workItem.getParameters().keySet()) {
            LOG.info(parameter + " = " + workItem.getParameters().get(parameter));
        }
        Map<String, Object> results = new HashMap<String, Object>();
        String firstName = (String) workItem.getParameter("FirstName");
        String lastName = (String) workItem.getParameter("LastName");
        String fullName = firstName + " " + lastName;
        results.put("FullName", fullName);
        return Optional.of(handler.completeTransition(workItem.getPhaseStatus(), results));
    }
    @Override
    public 
Optional<WorkItemTransition> 
abortWorkItemHandler(KogitoWorkItemManager manager, 
KogitoWorkItemHandler handler, KogitoWorkItem workItem, 
WorkItemTransition transition) {
        LOG.info("Aborting work item " + workItem);
        return Optional.of(this.workItemLifeCycle.newTransition("abort", workItem.getPhaseStatus(), workItem.getResults()));
    }
}
In WorkItemHandler's activateWorkItemHandler(...) method we can add business logic. This might be mean interacting with a web service, database, or other technical component and will mark workitem is completed successfully and  abortWorkItemHandler(...) methods will abort the workitem execution. In BAMOE 8, custom WorkItemHandler implemented the interface org.kie.api.runtime.process.WorkItemHandler and uses  executeWorkItem(...) and abortWorkItem(...) methods, but in BAMOE v9 these methods are not supported.