Search code examples
javaservlet-3.0wicket-6apache-cayenne

using CayenneRuntime in webapplication without web.xml


I have a Wicket application and I'm trying to implement separate configuration that can be changed remotely. That's the end goal, anyway.

What I'm trying to do is set up Cayenne to work by starting it manually, rather than using the web.xml file. I have tried a bunch of different things, but I'm not sure I fully understand how the context is applied to all threads.

I have tried creating a ServerRuntime in my Application class. I've also tried on my custom BasePage class that each page uses. I can get it to kind of work by doing the following on the BasePage, but it is inconsistent:

public class BasePage ....
    public static ServerRuntime runtime = new ServerRuntime("cayenne-config.xml");//This is in my BasePage class, but I've also tried this in the Application class

    @Override
    protected void init() { 
BaseContext.bindThreadObjectContext(Application.runtime.getContext());//This is in my BasePage class
    }

Like I said, that kind of works, but it isn't consistent. I keep getting errors on

BaseContext.getThreadObjectContext();

Error is this:

java.lang.IllegalStateException: Current thread has no bound ObjectContext.

I can't seem to find much information on this. I tried doing stuff like this, and accessing the runtime using these as well, but nothing is working consistently.

WebUtil.setCayenneRuntime(this.getServletContext(), runtime);
BaseContext.bindThreadObjectContext(WebUtil.getCayenneRuntime(((Application)getApplication()).getServletContext()).getContext());

Any help would be greatly appreciated.


Solution

  • I figured out a way to do this on my own.

    I'm extending CayenneFilter and overriding the init method.

    In there I copied nearly their exact code. I will be able to check for any config here and load the proper xml file. This obviously isn't the ironed out solution, but is definitely a step forward, and could be the way I end up doing this.

    Either way, here's what I have tested to be working.

    @WebFilter(filterName = "cayenne-config", displayName = "cayenne-config", urlPatterns = {"/*"})
    public class TestFilter extends CayenneFilter
    {
        @Override
        public void init(FilterConfig config) throws ServletException
        {
            this.checkAlreadyConfigured(config.getServletContext());
            this.servletContext = config.getServletContext();
            WebConfiguration configAdapter = new WebConfiguration(config);
            Collection modules = configAdapter.createModules(new Module[]{new WebModule()});
            ServerRuntime runtime = new ServerRuntime("cayenne-test.xml", (Module[])modules.toArray(new Module[modules.size()]));
            WebUtil.setCayenneRuntime(config.getServletContext(), runtime);
        }
    }
    

    I don't think the annotation is needed (I am specifying it all in the web.xml file), but I thought I would leave it here so you could see that it is changing.

    If I could find a way to change the config (FilterConfig) values (the init parameters), then I could just change that to the name of the xml file I want to use and not override this entire method. I couldn't figure out how to do that, but I'll look further later.

    If anyone has another better answer, I would love to hear it.