NoClassDefFoundError when trying to use external library to generate QR codes

I’m trying to generate QR codes with an external ibrary.
Included the following into the build.gradle:


 maven { url "https://jitpack.io" } 

also included to core module:


        compile('com.google.zxing:core:3.3.0')
        compile('com.google.zxing:javase:3.3.0')
        compile('com.github.kenglxn.QRGen:javase:2.3.0')
        compile('com.github.kenglxn.QRGen:core:2.3.0')

but getting this error below once “generarQR()” method is invoked.

I’m attaching the whole project. (see project accesstest.zip https://www.dropbox.com/s/g8fy05utc0asjwc/accesstest.zip?dl=0)
I’ve tried to use the libraries from outside the platform and it worked ok (see project prubeasCommandLine.zip https://www.dropbox.com/s/t97dmqrzpfapnul/prubeasCommandLine.zip?dl=0)

08:42:07.334 ERROR c.h.cuba.core.sys.ServiceInterceptor - Exception: 
java.lang.NoClassDefFoundError: net/glxn/qrgen/javase/QRCode
	at com.company.accesstest.service.QrServiceBean.getQrByteArray(QrServiceBean.java:12) ~[app-core-0.1-SNAPSHOT.jar:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_72]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_72]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_72]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_72]
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) [spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) [spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
	at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
	at com.haulmont.cuba.core.sys.ServiceInterceptor.aroundInvoke(ServiceInterceptor.java:115) ~[cuba-core-6.5.5.jar:6.5.5]
	at sun.reflect.GeneratedMethodAccessor106.invoke(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_72]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_72]
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:629) [spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:618) [spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
	at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70) [spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168) [spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) [spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) [spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
	at com.sun.proxy.$Proxy211.getQrByteArray(Unknown Source) [na:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_72]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_72]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_72]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_72]
	at com.haulmont.cuba.core.sys.remoting.LocalServiceInvokerImpl.invoke(LocalServiceInvokerImpl.java:94) [cuba-core-6.5.5.jar:6.5.5]
	at com.haulmont.cuba.web.sys.remoting.LocalServiceProxy$LocalServiceInvocationHandler.invoke(LocalServiceProxy.java:148) [cuba-web-6.5.5.jar:6.5.5]
	at com.sun.proxy.$Proxy52.getQrByteArray(Unknown Source) [na:na]
	at com.company.accesstest.web.atleta.AtletaBrowse.onButtonInClick(AtletaBrowse.java:43) [app-web-0.1-SNAPSHOT.jar:na]
	at com.company.accesstest.web.atleta.AtletaBrowse.generarQR(AtletaBrowse.java:36) [app-web-0.1-SNAPSHOT.jar:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_72]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_72]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_72]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_72]
	at com.haulmont.cuba.gui.xml.DeclarativeAction.actionPerform(DeclarativeAction.java:92) [cuba-gui-6.5.5.jar:6.5.5]
	at com.haulmont.cuba.web.gui.components.WebButton.performAction(WebButton.java:44) [cuba-web-6.5.5.jar:6.5.5]
	at com.haulmont.cuba.web.gui.components.WebButton.lambda$new$61446b05$1(WebButton.java:36) [cuba-web-6.5.5.jar:6.5.5]
	... 48 more
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.haulmont.cuba.gui.xml.DeclarativeAction.actionPerform(DeclarativeAction.java:92)
	... 55 more
Caused by: com.haulmont.cuba.core.global.RemoteException:
---
java.lang.NoClassDefFoundError: net/glxn/qrgen/javase/QRCode
	at com.haulmont.cuba.core.sys.ServiceInterceptor.aroundInvoke(ServiceInterceptor.java:127)
	... 60 more

thank you for your answer.

Hi,

The source of the problem is our deployment procedure with local tomcat instance. There are two aspects that leads to that error:

  1. JAR files are copied into tomcat instance with file names that include only Maven artifactId and version. For instance: core-2.3.0.jar
  2. We try to resolve compatibility issues if we see two files with the same name and different version. In fact we decide which file has greater version and remove file with the older version.

As a result, you will that only one “core” named library is deployed to tomcat with version “3.3.0”.

As a workaround you could disable the mechanism 2. Add sharedlibResolve = false property to deploy tasks of web and core modules:


task deploy(dependsOn: [assemble, cleanConf], type: CubaDeployment) {
    appName = 'app'
    appJars('app-global', 'app-gui', 'app-web')
    // add this
    sharedlibResolve = false
}

Actually, the authors of these two libraries are not so right. It is a bad practice to use “core” or “javase” as artifact ids without any prefixes.

We will try to rework our libraries resolving mechanism in the future, but currently we don’t see any good solutions of this problem.