Cannot run 2.0-RC1, NoClassDefFoundDefError

We’re trying to test Liquibase 2.0-RC1 the jar seems to have all sorts of problems around finding Main and Logger.  See 3 test cases and results below… can anyone assist?  Seems like the manifest is seriously broken.  Thanks in advance.

  1. When we try just running the jar, we get:
    $ java -jar liquibase.jar
    Failed to load Main-Class manifest attribute from liquibase.jar

  2. If we hack the manifest, we get this far:
    Exception in thread “main” liquibase.exception.ServiceNotFoundException: liquibase.exception.ServiceNotFoundException: liquibase.exception.ServiceNotFoundException: Could not find implementation of liquibase.logging.Logger
    at liquibase.logging.LogFactory.getLogger(LogFactory.java:19)
    at liquibase.logging.LogFactory.getLogger(LogFactory.java:30)
    at liquibase.integration.commandline.Main.main(Main.java:132)
    Caused by: liquibase.exception.ServiceNotFoundException: liquibase.exception.ServiceNotFoundException: Could not find implementation of liquibase.logging.Logger
    at liquibase.servicelocator.ServiceLocator.newInstance(ServiceLocator.java:146)
    at liquibase.logging.LogFactory.getLogger(LogFactory.java:17)
    … 2 more
    Caused by: liquibase.exception.ServiceNotFoundException: Could not find implementation of liquibase.logging.Logger
    at liquibase.servicelocator.ServiceLocator.findClass(ServiceLocator.java:101)
    at liquibase.servicelocator.ServiceLocator.newInstance(ServiceLocator.java:144)
    … 3 more

  3. We tried just running the bar Java command and providing the absolute path to liquibase.integration.commandline.Main class, and we tried using the bundled liquibase script.  In that case we get this error:

$ ./liquibase status
Exception in thread “main” java.lang.NoClassDefFoundError: liquibase/integration/commandline/Main
Caused by: java.lang.ClassNotFoundException: liquibase.integration.commandline.Main
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
Could not find the main class: liquibase.integration.commandline.Main.  Program will exit.

Oh also, the Ant task works, and I’m able to run it as an ant task.  It’s really strange.

OK, found the issue.  The manifest definitely is hosed, but regarding the other issues, we were passing around commands that were corrupted by nonprinting characters that crept into the clipboard buffer.

It looks like it, thanks.  I’ve been testing it using the liqubase.bat file and that passes in the main class.

The newest build at http://liquibase.org/ci will have the fix, along with the next release.

Nathan

I have the same problem in RC2 using Liquibase from Java code.

liquibase.exception.ServiceNotFoundException: liquibase.exception.ServiceNotFoundException: liquibase.exception.ServiceNotFoundException: Could not find implementation of liquibase.logging.Logger

Is there anything I need to configure for logging in 2.0 that wasn’t needed for 1.9.5?

Hi,
I am getting the same error with rc1 svn rev 1379 when I run under Websphere.  On Tomcat, everything seems to work.  On Websphere 6.1 I get the following exception:

    Caused by: liquibase.exception.ServiceNotFoundException: liquibase.exception.ServiceNotFoundException: liquibase.exception.ServiceNotFoundException: Could not find implementation of liquibase.logging.Logger       at liquibase.logging.LogFactory.getLogger(LogFactory.java:19)       at liquibase.integration.spring.SpringLiquibase.(SpringLiquibase.java:125)       at

I am trying RC2, to see if it fixes the problem.

Alana

Hi again,

Getting the same error with RC2.  I traced through the code an found that CloasLoaderResourceAccessor.getResource(liquibase/logging) returns an enumeration with no elements.
This causes nothing to be added to List associated with the key  “liquibase.Logging.Logger” on classesBySuperclass.  This is the root of the error.    The Websphere classLoader object is
com.ibm.ws.classloader.CompoundClassLoader.  I am now trying to figure out why the classloader returns nothing.  Any ideas?

Thanks,
Alana

Hi,

I was able to get past this exception by setting an option in Websphere to load classes with the local class loader first (parent last)
This is not the best option to run in production though:  According to IBM’s doc at

http://publib.boulder.ibm.com/infocenter/wasinfo/v6r1/topic/com.ibm.websphere.base.doc/info/aes/ae/urun_rappsvr.html

If you select Parent last, your application can override classes contained in the parent class loader, but this action can potentially result in ClassCastException or linkage errors if you have mixed use of overridden classes and non-overridden classes.

Since this is not the default setting, I am sure our business partners would not want it set in their production environments.

Thanks,
Alana

I changed the way classes are looked up yesterday, which may help.  I’m trying to get a new RC out (this is the RC that will have a maven build, so that is the main problem).  When it is out (or if you want to build a new version from trunk) take a look with the default websphere config and let me know if it works for you.

Nathan

In a J2SE environment, should this work with the latest changes if I just use the context class loader of the current thread?

It should, if I’m understanding your question right.

Nathan

It seems that my packagesToScan is empty.  Do all the ServiceLocator magic depend on having Liquibase-Package entry or entries in your Manifest file of your jar?

What I am trying to do is the following.  I’m using Izpack to create an installer for patches to my application.  This patch installer will use Liquibase to modify the database.  In order to do that I have some Izpack actions that perform migrations and rollbacks directly from Java using the Liquibase API.  So I’m not writing any extensions, just trying to get it working within this environment.

It would depend on having the Liquibase-Packages in MANIFEST.MF.  The standard jar value is:

Liquibase-Package: liquibase.change,
liquibase.database,
liquibase.parser,
liquibase.precondition,
liquibase.serializer,
liquibase.sqlgenerator,
liquibase.executor,
liquibase.snapshot,
liquibase.logging,
liquibase.ext

Nathan

If you are including the standard liquibase.jar, it should be fine because that will have the MANIFEST.MF file there with the Liquibase-Packages property. 

I did get RC3 released, you could see if that helps as well too.

Nathan

Hi,

I tried the latest version from the trunk and I am still seeing the same error under Websphere. 

Alana

Thanks Nathan, in my setup the contents of the liquibase jar is rolled into the patch (excluding the liquibase manifest).

Will add the entries you listed and hopefully it will fix the problem.

Ok still having issues.

What I have is the following:
A single jar created by the Izpack installer.  Apart from the other resources for the installation it also contains the Liquibase classes.
The META-INF/MANIFEST.MF file includes the entries from Nathan’s earlier post.

With logging set to debug I can see that Liquibase is trying to find the implementations of the interfaces, so it does process the manifest file.

Problems:
a) In a setup like this where it is searching (apparently repeatedly) through a large jar file, it is very very very slow.
b) It finds the files, but doesn’t seem to find any matches.
c) For all practical purposes it seems to have entered an infinite loop in the finding process, it just goes on and on and on.  Still waiting for it to exit. (Ok, it finally finished, not sure it worked).

I’ll try to continue working on it tonight so that I can respond better on the forum responses…

I am going to move the websphere issue over to a new thread.

Alana

I have bypassed the Manifest limitation by modifying the Liquibase source to check for a system property “liquibase.scan.packages”.  I can send you a patch as it would be nice if we could have this in the Liquibase distribution.

The checks for classes takes about 2 - 3 minutes in my VM. 

What I would like to be able to do is to tell the ServiceLocator, “I know what classes I have that implement the interfaces, here take my list instead of looking for implementations in the jar.”  I’m willing to help in writing code to be able to do this for inclusion into Liquibase, but I’ll need information on what the default implementations are for normal use…

If you have a patch for what worked better for you, I’d definitely look at incorporating it in.  I tried running the code through a profiler, and I wasn’t seeing where the performance hit was coming from.  There is definitely time for ClassLoader.loadClass() but it does appear to only call that for classes in the packages specified in MANIFEST-MF.  Do you have a profiler at all you could run your update process through?

The idea behind having the packages listed in MANIFET.MF is to support auto-loading and auto-finding of extension (new Change, Database, SqlGenerator, ChangeLogParser, etc classes).  See http://liquibase.org/extensions for more info.

Since we don’t want to load and scan all classes, we need a way to list the package to check, and that is what the manifest.mf list is for.  I wanted to have the default liqubase classes loaded the same way extensions are to ensure there is no problems with the process and that no special treatment is given to core classes vs extension classes.

Nathan