java.lang.NoSuchMethodError: com.google.common.collect.FluentIterable.toList()Lcom/google/common/collect/ImmutableList;
Asked Answered
S

3

12

I'm using the Google Guava library for tasks like sorting and filtering of a java.util.List<T> in a Java EE 7 application.

Given below an example of filtering a java.util.List<T> based on a list of filters in a CDI bean.

@Named
@ViewScoped
public class Bean extends LazyDataModel<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    private final class Filtering implements Predicate<T> {

        private final Map<String, Object> filters;

        public Filtering(Map<String, Object> filters) {
            this.filters = filters;
        }

        @Override
        public boolean apply(T p) {
            if (p == null) {
                return false;
            }

            Integer id = (Integer) filters.get("id");

            if (id != null && !p.getId().equals(id)) {
                return false;
            }

            BigDecimal size = (BigDecimal) filters.get("size");

            if (size != null && ((p.getSize().compareTo(size) < 0))) {
                return false;
            }
            return true;
        }
    }
}

The nested class can be used to filter a java.util.List<T> from within the CDI bean as follows.

List<T> list = //Initialize the list here to be filtered.

//...

list = FluentIterable.from(list).filter((new Filtering(filters))).toList();

Where filters is a java.util.Map<String, Object> holding a list of filters.


This was working fine previously in a Java EE application with JSF Managed Beans (on GlassFish 4.0).

I migrated this application to GlassFish 4.1 with CDI Managed Beans and the following exception occurred.

SEVERE:   java.lang.NoSuchMethodError: com.google.common.collect.FluentIterable.toList()Lcom/google/common/collect/ImmutableList;
    at util.mesurements.custom.beans.BackNeckDepthManagedBean.load(BackNeckDepthManagedBean.java:184)
    at org.primefaces.component.datatable.DataTable.loadLazyData(DataTable.java:838)
    at org.primefaces.component.datatable.feature.FilterFeature.encode(FilterFeature.java:102)
    at org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:78)
    at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:919)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1863)
    at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:582)
    at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
    at org.primefaces.component.api.UIData.visitTree(UIData.java:692)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
    at javax.faces.component.UIForm.visitTree(UIForm.java:371)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
    at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:403)
    at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:322)
    at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:219)
    at org.primefaces.context.PrimePartialViewContext.processPartial(PrimePartialViewContext.java:60)
    at javax.faces.component.UIViewRoot.encodeChildren(UIViewRoot.java:1004)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1856)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:430)
    at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:133)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:72)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at filter.NoCacheFilter.doFilter(NoCacheFilter.java:28)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
    at java.lang.Thread.run(Thread.java:722)

I'm using Guava 17.0 on both the applications (double checked it).

Why does Guava dislike CDI beans. What might be the solution/workaround?


UPDATE :

I tried changing the version to 18.0 but nothing new happened.

Sivie answered 20/10, 2014 at 22:44 Comment(2)
Are you using the library local within your WAR or is it deployed to the app server?Tweeddale
The library is local to WAR. It is stored in the /WEB-INF/Lib directory and added to the classpath (in both the applications - one with JSF managed beans and the other with CDI beans).Sivie
C
17

You have multiple versions of Guava on your classpath. NoSuchMethodError in a Guava class comes here on SO maybe once per week. Switching to a newer version won't help as long you don't get rid of the old one. Print out the location of FluentIterable.class and get rid of that JAR.

As Frank Pavageau commented, this location can be obtained as

FluentIterable.class.getProtectionDomain().getCodeSource().getLocation().toExte‌​rnalForm()
Cantabile answered 21/10, 2014 at 7:42 Comment(4)
To complete the answer, the location of the class is obtained with FluentIterable.class.getProtectionDomain().getCodeSource().getLocation().toExternalForm().Kragh
The duplicate JAR comes from Weld/GlassFish itself. you'll need to downgrade to 16 and mark it as provided (don't bundle it). This is however likely a regression issue w/ GF 4.1 as it seems like classloader isolation worked better in 4.0Tweeddale
Another way to see the class locations with GlassFish is to add -verbose:class to the server-config JVM options (can be done using the admin GUI or editing the domain.xml; probably there is an asadmin command, too) and starting the server with asadmin start-domain --verbose.Darmstadt
if you are using Gradle it's could be more useful to get dependency insights ./gradlew :app:dependencyInsight --configuration compile --dependency guava To get an idea which jar dependant from old guavaPylon
D
6

This is a known GlassFish issue. With GlassFish 4.1 and no other modifications, Guava 13.0.1 is used so when you use features not present in that version, you will get errors like the one you stated. In my case, it was java.lang.IncompatibleClassChangeError: Implementing class.

In the comments of the bug report it is suggested to replace glassfish/modules/guava.jar. This seems to be the easiest solution. Another approach is to use a custom class loader.

Edit: If you add <class-loader delegate="false"/> to your glassfish-web.xml, then Guava is loaded from the WAR.

Darmstadt answered 2/6, 2015 at 12:51 Comment(1)
<class-loader delegate="false"/> in glassfish-web.xml solved it for me.Kitchen
M
2

I was getting below error java.lang.NoSuchMethodError: com.google.common.collect.FluentIterable.append(Ljava/lang/Iterable;)Lcom/google/common/collect/FluentIterable; switching to guava version 20.0 from 16.0.1, fixed the issue for me.

Marra answered 14/1, 2020 at 10:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.