Search code examples
ejbwicketcglib

Upgrading Wicket 9.0.0 to 9.3.0: runtime error when try to access database


I am attempting to upgrade from Wicket 9.0.0 to Wicket 9.3.0. When I change the version in a quick-start application, everything is fine.

The problem occurs in my real application, where we were originally using Jakarta Enterprise Beans 8.0.0. At runtime, when a database access was attempted, we got an exception with the following message:

Last cause: net.sf.cglib.proxy.MethodInterceptor not found by org.objectweb.asm [23]

Trying to use Jakarta EE 9.1 instead

I changed my pom.xml as follows:

        <jakartaee>9.1.0</jakartaee>
        <wicket.version>9.3.0</wicket.version>

I downloaded the jar for Jakarta EE 9.1, changed "javax" to "jakarta" throughout my application, rebuilt it and tried to run again.

The result was still not perfect, but significantly better than before: a plain old null pointer exception instead of any weird errors about cglib.

Here's the section of code that now causes the trouble:

    @EJB(name = "AdminNotesFacade")
    private AdminNotesFacade adminNotesFacade;


    public AdminNotesFacade getAdminNotesFacade() {
        return adminNotesFacade; //ACTUALLY RETURNS NULL
    }

So now the big question is: what do I need to do/change to make the @EJB work instead of returning null?

Checking the Payara log, I get this error:

java.lang.RuntimeException: Unable to load the EJB module. DeploymentContext does not contain any EJB. Check the archive to ensure correct packaging for D:\Dev\icase2\target\icase2. If you use EJB component annotations to define the EJB, and an ejb or web deployment descriptor is also used, please make sure that the deployment descriptor references a Java EE 5 or higher version schema, and that the metadata-complete attribute is not set to true, so the component annotations can be processed as expected at org.glassfish.ejb.startup.EjbDeployer.prepare(EjbDeployer.java:189)

Adding further details, 2022-05-06

I wonder if we were going off on the wrong track when we thought that we could fix this by upgrading our jakartaee version. From Wicket 9.0 to 9.3 is only a change of minor version and you wouldn't expect to have to make such fundamental changes to get a minor upgrade working.

I've tried using Wicket 9.9.1 instead, in case this problem has been fixed in more recent versions, but it's exactly the same.

Anyway, I have created a very small "quick-start" application, based on Wicket's own templates, to reproduce the problem. I have stuck with the original "javax" version, and added just one EJB - a JavaMail bean. I think it's probably interesting to know that it's not a specifically database-related issue. We just can't seem to load any EJBs at all.

In the Wicket 9.0.0 version, a simple form is displayed on the home page, allowing the user to enter their email address. When they submit the form, a test message is sent to that address. It works fine.

Then if I change the Wicket version to 9.3.0 but make no other changes at all, it doesn't even get to the stage of displaying the home page, it immediately crashes with the message "Last cause: net.sf.cglib.proxy.MethodInterceptor not found by org.objectweb.asm [23]"

For what it's worth, here's the code that triggers the error.

    public class HomePage extends WebPage {

        @EJB(name = "EmailerFacade")
        private EmailerFacade emailerFacade;

        private static final long serialVersionUID = 1L;

        private String sendTo = "";

        public HomePage(final PageParameters parameters) {
            super(parameters);

            add(new Label("version", getApplication()
                .getFrameworkSettings().getVersion()));

            FeedbackPanel feedback = new FeedbackPanel("feedback");
            add(feedback);

            final Form emailForm = new Form("emailForm") {
                @Override
                protected void onSubmit() {
                    emailerFacade.sendMessage(sendTo, "Test message from quick-start", 
                            "Version is " + getApplication().getFrameworkSettings()
                                    .getVersion());
                    info("Tried to send message to " + sendTo);
                }
            };
            add(emailForm);

            final TextField<String> emailAddress = new TextField<>("emailAddress", 
                new PropertyModel<>(this, "sendTo"));
            emailAddress.setLabel(Model.of("Email address"));
            emailAddress.setRequired(true);
            emailForm.add(emailAddress);
        }
    }


Solution

  • This answer was actually provided by Sven Meier. He commented:

    Use the new system property to switch to ByteBuddy in Wicket 9.x:

    -Dwicket.ioc.useByteBuddy=true

    To expand a bit on this, I found I needed to do three things:

    1. Set the system property "wicket.ioc.useByteBuddy" to true as specified by Sven
    2. Add a dependency on byte buddy
    3. Upgrade to a higher version than I was initially attempting to do: 9.3.0 was not good enough. I see in a comment above by Sven, he says that the migration to byte buddy was actually done in 9.5. So in fact I upgraded to the latest version, which is currently 9.9.1.

    Here is the dependency on byte buddy that I added:

                <dependency>
                    <groupId>net.bytebuddy</groupId>
                    <artifactId>byte-buddy</artifactId>
                    <version>1.12.10</version>
                </dependency>