0
votes

Just started experimenting with Kotlin (1.2.60) & Java (EE8). All is deployed successfully in an EAR file onto JBoss WildFly 13.0.0.Final using Java EE 8, EJB 3.2. No exceptions are shown in the log.

I've created a Kotlin EJB:

@Stateless
@LocalBean
open class NOTiFYEJB {

    open val logger = LoggerFactory.getLogger("NOTiFYEJB")

    open fun sayHelloKotlinWorld() = {
        logger.info(">>>>> sayHelloKotlinWorld .....")
    }
}

Which is 'registered' on WildFly 13:

08:06:26,131 INFO [org.jboss.as.ejb3.deployment] (MSC service thread 1-1) WFLYEJB0473: JNDI bindings for session bean named 'NOTiFYEJB' in deployment unit 'subdeployment "NOTiFYwellJAR.jar" of deployment "NOTiFYwell.ear"' are as follows:

java:global/NOTiFYwell/NOTiFYwellJAR/NOTiFYEJB!com.notifywell.kotlin.ejb.NOTiFYEJB java:app/NOTiFYwellJAR/NOTiFYEJB!com.notifywell.kotlin.ejb.NOTiFYEJB java:module/NOTiFYEJB!com.notifywell.kotlin.ejb.NOTiFYEJB ejb:NOTiFYwell/NOTiFYwellJAR/NOTiFYEJB!com.notifywell.kotlin.ejb.NOTiFYEJB java:global/NOTiFYwell/NOTiFYwellJAR/NOTiFYEJB java:app/NOTiFYwellJAR/NOTiFYEJB java:module/NOTiFYEJB

I inject this into a @model Java Pojo and call the method:

@Model
@Path("/")
public class NOTiFYwellModel {

    @Inject
    private NOTiFYEJB nOTiFYEJB;

    public NOTiFYwellModel() {
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/say-hello-kotlin-world")
    public Response sayHelloKotlinWorld() {
        logger.info(">>>> sayHelloKotlinWorld nOTiFYEJB = {}", nOTiFYEJB);

        nOTiFYEJB.sayHelloKotlinWorld();

        return null; // Just for test
    }
}

When I run the Unit test:

String url = "http://localhost:8080/NOTiFYwell/notifywell/say-hello-kotlin-world";

HttpGet httpGet = new HttpGet(url);
httpGet.setHeader(CONTENT_TYPE, APPLICATION_JSON);

// Execute and get the response.
HttpClient httpClient = HttpClientBuilder.create().build();
HttpResponse response = httpClient.execute(httpGet);

The method in the @Model NOTiFYwellModel class is called:

08:07:00,459 INFO [com.notifywell.model.NOTiFYwellModel] (default task-1) >>>> sayHelloKotlinWorld nOTiFYEJB = Proxy for view class: com.notifywell.kotlin.ejb.NOTiFYEJB of EJB: NOTiFYEJB

But the next line which calls the method in the (Injected) Kotlin EJB is not executed.

nOTiFYEJB.sayHelloKotlinWorld();

It is as though the 'local' interface is not found.

This 'architecture/design' is working fine everywhere else when I inject a (local) Java EJB.

Are you able to use Weld CDI to @Inject a Kotlin EJB into a Java Class?

1
@duffymo: ejb 3.2 and the lightweight pure web versions is very much 201x (even with x approaching 9) All standardized and not requirering spring so no need for all the spring-* wrappers - Kukeltje
I like the simplicity of EJB 3.2 with CDI on EE8 and the speed of JBoss WildFly 13. I do find that rather ironic (criticising 2010/2020s EJBs) when Spring had to launch Spring Boot as too many people were finding Spring far too complicated. A Framework for a Framework. I know it now (finally) has annotations but it was XML configuration hell for many years! - NOTiFY
What do you mean the method is ignored? Not called at all or blowing up? Have you debugged it? From EE PoV this normally works. Also, if you are running a true unit test, your EJB probably won't work because there is no EJB container active. - Siliarus
The "unit" test is a Web Service call. See the annotations: @GET @Produces(MediaType.APPLICATION_JSON) @Path("/say-hello-kotlin-world"). It is ignored / not called as the 'logger' in the Kotlin EJB is not printing the message ">>>>> sayHelloKotlinWorld .....". Nothing "blows-up". - NOTiFY

1 Answers

0
votes

Unlike EJB 3.2 with Java EE 8, I needed to create and implement an Interface on my Kotlin EJB, rather than just annotating the EJB.

I also needed to 'override' & specify ': Unit' for my void method:

Kotlin EJB:

@Stateless
@LocalBean
open class NOTiFYKotlinEJB : NOTiFYKotlinEJBInterface {

    /**
     *
     */
    override fun sayHelloKotlinWorld(): Unit {
        println("***** sayHelloKotlinWorld .....")
    }
}

Interface:

interface NOTiFYKotlinEJBInterface {

    fun sayHelloKotlinWorld() : Unit {}

}

My @Model POJO calls the Kotlin EJB method and outputs:

22:31:31,175 INFO [com.notifywell.model.NOTiFYwellModel] (default task-1) >>>> sayHelloKotlinWorld nOTiFYEJB = Proxy for view class: com.notifywell.kotlin.ejb.NOTiFYKotlinEJB of EJB: NOTiFYKotlinEJB 22:31:31,191 INFO [stdout] (default task-1) ***** sayHelloKotlinWorld .....