Hi,
when I use liquibase’s ant task updateDatabase in my test build.xml everything works fine(except warning about LoggingExecutor). But when I try to use it actually in my build system I have this exception:
Could not create type updateDatabase due to liquibase.exception.ServiceNotFoundException: liquibase.exception.ServiceNotFoundException: liquibase.exception.ServiceNotFoundException: Could not find implementation of liquibase.logging.Logger
at org.apache.tools.ant.ProjectHelper.addLocationToBuildException(ProjectHelper.java:508)
at org.apache.tools.ant.taskdefs.MacroInstance.execute(MacroInstance.java:397)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
at sun.reflect.GeneratedMethodAccessor10.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.taskdefs.Sequential.execute(Sequential.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at com.orangevolt.tools.ant.SwitchTask.execute(SwitchTask.java:60)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
at sun.reflect.GeneratedMethodAccessor10.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.Target.execute(Target.java:357)
at org.apache.tools.ant.Target.performTasks(Target.java:385)
at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1337)
at org.apache.tools.ant.Project.executeTarget(Project.java:1306)
at com.google.ras.installer.ant.Installer.executeTargets(Installer.java:170)
at org.apache.tools.ant.Project.executeTargets(Project.java:1189)
at com.google.ras.installer.ant.Installer$1.run(Installer.java:84)
at java.lang.Thread.run(Unknown Source)
For installation my application uses exe4j, it runs main class which uses classes from ant.jar to run targets from build.xml. Have you and idea why it happens?
There have been some changes to how the ServiceLocator works in the upcoming RC6. That will hopefully solve the problem. If you could try building from a source checkout, and test it that would be great. The classloader issues like this is one of the main issues holding up 2.0 final.
Nathan
Nathan, why do you not want add your own implementation of the Logger?
I did not look in the detail of the issue, I guess you wanna avoid hard coded Logger implementation, but allow using the Logger from classpath?
Good point. But you can add own implementation as a last chance if no other exists at start up.
Manage classloader/locatorService searching all implementations. If no “user” Logger is found, use own one.
For some strange use cases, i.e. you own Logger throws exception by logging, use NullLogger as it done by maven team.
Hi Nathan,
Originally posted by: Nathan
There have been some changes to how the ServiceLocator works in the upcoming RC6. That will hopefully solve the problem. If you could try building from a source checkout, and test it that would be great. The classloader issues like this is one of the main issues holding up 2.0 final.
Nathan
I ran my installer also using last snapshot, the same problem.
Originally posted by: Taras_Petrytsyn
I ran my installer also using last snapshot, the same problem.
Thanks for checking, I’ll take a look.
Nathan
Originally posted by: taranenko
Nathan, why do you not want add your own implementation of the Logger?
I did not look in the detail of the issue, I guess you wanna avoid hard coded Logger implementation, but allow using the Logger from classpath?
Good point. But you can add own implementation as a last chance if no other exists at start up.
Manage classloader/locatorService searching all implementations. If no "user" Logger is found, use own one.
For some strange use cases, i.e. you own Logger throws exception by logging, use NullLogger as it done by maven team.
We ship a logging class liquibase.logging.jvm.JavaUtilLogger which uses the java.util.logging package. The ServiceLocator class looks for the best logging class to use and may find a different implementation if someone wants to use log4j or slf4j. The fact that it’s not finding the default logger is a problem with the ServiceLocator class.
Hi Nathan,
We found the root of problem. During building the install.exe we unzip all libs that are used only for installation process, to the same folder, there is no problem with java classes, because they are in different packages, and generate our own MANIFEST.MF file in META-INF folder…and our generated file replace liquibase file. And this is actually the problem, because ServiceLocator uses System settings or MANIFEST.MF to get information what packages should be scanned for classe. In our case there was no info neither in System settings nor in MANIFEST.MF, so ServiceLocator didn’t know any package for scanning.
I’m glad you found the issue. We only go by classes listed in the MANIFEST.MF rather than hard coding anything to ensure that everything is completely configurable from a extensibility standpoint. It may be worth making a default, though, to prevent issues like this.
Nathan