My problem is deceptively simple but I am unable to find the answer. Through Java and JDBI, I am able to retrieve the image from MySQL database and store it locally. But when I try with a rest api, it is giving the error in the attached screenshot. I have searched for this quite a bit but am unable to find a solution.
The stack trace is as below:
Type Exception Report Message java.lang.IllegalStateException: No container builder available for java.sql.Blob Description The server encountered an unexpected condition that prevented it from fulfilling the request. Exception javax.servlet.ServletException: java.lang.IllegalStateException: No container builder available for java.sql.Blob org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:489) org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427) org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388) org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341) org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) Root Cause java.lang.IllegalStateException: No container builder available for java.sql.Blob org.skife.jdbi.v2.ContainerFactoryRegistry.createBuilderFor(ContainerFactoryRegistry.java:73) org.skife.jdbi.v2.Query.first(Query.java:271) org.skife.jdbi.v2.sqlobject.ResultReturnThing$SingleValueResultReturnThing.result(ResultReturnThing.java:110) org.skife.jdbi.v2.sqlobject.ResultReturnThing.map(ResultReturnThing.java:46) org.skife.jdbi.v2.sqlobject.QueryHandler.invoke(QueryHandler.java:43) org.skife.jdbi.v2.sqlobject.SqlObject.invoke(SqlObject.java:212) org.skife.jdbi.v2.sqlobject.SqlObject$3.intercept(SqlObject.java:127) org.skife.jdbi.v2.sqlobject.CloseInternalDoNotUseThisClass$$EnhancerByCGLIB$$8d85a881.retrieveImage(<generated>) com.sample.obs.factory.BooksFactory.retrieveImage(BooksFactory.java:188) com.sample.obs.model.Books.listAllBooks(Books.java:378) com.sample.obs.util.BooksRest.listAllBooks(BooksRest.java:29) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:498) org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144) org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161) org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:205) org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99) org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389) org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347) org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102) org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326) org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) org.glassfish.jersey.internal.Errors.process(Errors.java:315) org.glassfish.jersey.internal.Errors.process(Errors.java:297) org.glassfish.jersey.internal.Errors.process(Errors.java:267) org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305) org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154) org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473) org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427) org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388) org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341) org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Adding the rest api and the listAllBooks method below :
@GET @Produces(MediaType.APPLICATION_JSON) public final Books[] listAllBooks() { Books b = new Books(); Books[] shelf = b.listAllBooks(); return shelf; } public final Books[] listAllBooks() { Books[] bList = BooksFactory.listAllBooks(); for(Books b: bList) { String path = "E:\" + b.getBookId() + ".png"; Blob imageBlob = BooksFactory.retrieveImage(b.getBookId()); try { byte[] image = handleBlob(imageBlob); if (image != null) { FileOutputStream fos = new FileOutputStream(path); fos.write(image); fos.close(); b.setImageUrl(path); } else { System.out.println("Image not available"); b.setImageUrl(null); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } int avail = BooksFactory.retrieveAvailableCopies(b.getBookId()); b.setAvailableCopies(avail); } return bList; }
The DAO and Factory methods return a Blob and I have a mapper for getting the blob from the DB.
Please guide as to how to solve this.
Advertisement
Answer
I finally found the solution to my issue. I added the below code to the dbi object.
dbi.registerContainerFactory(new ContainerFactory<Blob>(){ @Override public boolean accepts(Class<?> arg0) { return false; } @Override public ContainerBuilder<Blob> newContainerBuilderFor(Class<?> arg0) { return newContainerBuilderFor(arg0); } });
I followed the this link for the solution.