baffling logback bug TimeBasedArchiveRemover$ArhiveRemoverRunnable - java

Logback 1.1.7
This was during a "production" run: stack trace from Exception (actually NoClassDefFoundError is an Error):
Exception in thread "main" java.lang.NoClassDefFoundError: ch/qos/logback/core/rolling/helper/TimeBasedArchiveRemover$ArhiveRemoverRunnable
at ch.qos.logback.core.rolling.helper.TimeBasedArchiveRemover.cleanAsynchronously(TimeBasedArchiveRemover.java:231)
at ch.qos.logback.core.rolling.TimeBasedRollingPolicy.rollover(TimeBasedRollingPolicy.java:178)
at ch.qos.logback.core.rolling.RollingFileAppender.attemptRollover(RollingFileAppender.java:204)
at ch.qos.logback.core.rolling.RollingFileAppender.rollover(RollingFileAppender.java:183)
at ch.qos.logback.core.rolling.RollingFileAppender.subAppend(RollingFileAppender.java:224)
at ch.qos.logback.core.OutputStreamAppender.append(OutputStreamAppender.java:100)
So I looked at the source: that class ArhiveRemoverRunnable does indeed exist in the .java file where it should have been instantiated on l. 231 (with that mis-spelling)...
Then I unpacked the executable jar (logback-core-1.1.7.jar): again, the file TimeBasedArchiveRemover$ArhiveRemoverRunnable.class exists in the package, as does file TimeBasedArchiveRemover.class.
This error is not going to happen that often: it is obviously when the "rolling" logger decides it's time to clean up the directory.
Anyone got any idea why this might happen? Troublingly I find no evidence of anyone else experiencing this...!

Potential workaround (pending):
I thought the answer to this might be to extract the source files for this .jar, edit the offending class, compile and repackage as an executable jar, and then use instead of the downloaded jar. In order to do this I started a new Gradle project in Eclipse, imported the entire source package, etc. The thing compiles (builds) OK in Eclipse-with-Gradle, with no complaints of the "NoClassDef" type...
But I'm having difficulties actually producing this executable jar. It'd be a nice thing to be able to accomplish: ability to tweak and test a downloaded dependency in some way (if really necessary).
Current not so satisfactory workaround:
In fact I have no need for a "time-based" archive remover. I'm quite happy just having archives removed on the basis of the size of all the files in the logging directory. This answer appears to solve this. However, logback is quite a beast: I'm not entirely sure: is "archive removal" the same thing as "rollover"?
If the Error occurs again, of course, I shall have to make a special utility method to log every LOGGER.xxx command within a try...catch.

Related

java.lang.NoClassDefFoundError when using class from another module

I added dependency of a custom jar(say some-jar.jar) in a module's pom.xml where I need to write my code inside say CustomClass.java. Now, some-jar.jar contains AnotherClass.class which I need to use in my code.
After I finish my code, build succeeds and I am able to successfully deploy the application.
But when the execution reaches my code, it throws an ERROR(not an exception) saying
java.lang.NoClassDefFoundError: com/some/package/AnotherClass
. . . and the usual stack trace.
I understand this is happening because JVM is not able to locate this file at Runtime even though at compile time it was located, but what is the solution here? What do I need to do to make it available at Runtime.
Unfortunately, due to some restrictions I cannot disclose any more information than this issue. Lets see, if it is even required.
You can either specify your dependencies in classpath like this or make a fat jar (google it)

Optaplanner - The Website resource does not exist

I'm making a runnable jar for my project, and i keep getting this error when it starts generating the benchmark report:
Exception in thread "main" java.lang.IllegalStateException: The websiteResource (twitterbootstrap/css/bootstrap-responsive.css) does not exist.
at org.optaplanner.benchmark.impl.report.WebsiteResourceUtils.copyResource(WebsiteR esourceUtils.java:57)
at org.optaplanner.benchmark.impl.report.WebsiteResourceUtils.copyResourcesTo(WebsiteResourceUtils.java:33)
at org.optaplanner.benchmark.impl.report.BenchmarkReport.writeHtmlOverviewFile(BenchmarkReport.java:738)
at org.optaplanner.benchmark.impl.report.BenchmarkReport.writeReport(BenchmarkReport.java:287)
at org.optaplanner.benchmark.impl.DefaultPlannerBenchmark.benchmarkingEnded(DefaultPlannerBenchmark.java:315)
at org.optaplanner.benchmark.impl.DefaultPlannerBenchmark.benchmark(DefaultPlannerBenchmark.java:109)
Everything else works fine since i added "resources/" infront of the drools and the benchmarkConfig paths.
Since there are a few more resources just for the benchmark, i probably would need to do the same for them also.
How can i get access to the resources for the benchmarks?
Sounds like you're building from source with an IDE (Eclipse/IntelliJ/NetBeans/...) and your project isn't set up correctly to also copy *.css files as classpath resources (so it has a specific exclude for css somewhere).
With a modern IntelliJ IDEA version, opening the pom.xml file, this definitely doesn't happen. With a modern Eclipse/NetBeans version, I'd presume the same.

Grails 2.1.1 - How to develop a plugin with an AstTransformer?

I want to replace the auto injected log object, which is of type org.apache.commons.logging.Log with an object of type org.slf4j.Logger, so that I can use it properly with Logback.
Therefore I need to create a ...Transformer class (written in Java) - that's what I got from Graeme Rocher over at the "grails-user" mailing list. I'm also aware that I have to pack this ...Transformer class within a plugin and make it a *.jar archive which I can load within the lib/ folder of the plugin. But I guess I'm doing something wrong here as I have the class, along with a META-INF folder which contains the MANIFEST.MF file as well as another folder services which holds the following file org.codehaus.groovy.transform.ASTTransformation which holds just one String: the canonical name of the ...Transformer class.
Now, if I try to do a grails clean everything is fine, BUT if I try to run grails package-plugin the console comes up with a java.lang.ClassNotFoundException.
Clipping from Stacktrace:
| Packaging Grails application...
| Error Fatal error during compilation org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Could not instantiate global transform class my.package.ast.LoggingTransformation specified at jar:file:/C:/Source/MyGrailsAST/lib/replace-logging-logback-ast.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation because of exception java.lang.ClassNotFoundException: my.package.ast.LoggingTransformation
1 error
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Could not instantiate global transform class my.package.ast.LoggingTransformation specified at jar:file:/C:/Source/MyGrailsAST/lib/replace-logging-logback-ast.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation because of exception java.lang.ClassNotFoundException: my.package.ast.LoggingTransformation
Does anybody have some experience with Grails plugins which handle with AstTransformer and could give me some advice on this? Is there a good tutorial out there which I haven't seen so far?
Please let me know ;)
so, after some research, browsing and finally asking at the Grails Mailing List (see the mailing list archives at: http://grails.1312388.n4.nabble.com/Grails-user-f1312389.html I found a solution.
my goal was to create a Globals ASTTransformation, to inject a org.slf4j.Logger object instead of the usual org.apache.commons.logging.Log object into every Artefact class without annotation.
so, here are the steps:
I created Java class similar to https://github.com/grails/grails-core/blob/master/grails-logging/src/main/groovy/org/codehaus/groovy/grails/compiler/logging/LoggingTransformer.java but with my own implementation of the org.slf4j.Logger object. It is crucial that you place the Java.class under the following package: org.codehaus.groovy.grails.compiler as
Grails scans for classes that are annotated with #AstTransformer in this package. (Graeme Rocher)
and pack it into a JAR along with its MANIFEST.MF file within the META-INF/ folder. A META-INF/services directory with all its stuff is not needed as Graeme Rocher stated:
You do not need the META-INF/services stuff and I would remove it as it is probably complicating matters.
So, I guess this statement was more related to my specific problem as I only have one #AstTransformer class within my plugin, but that's just a guess. And I haven't searched for further informations on this topic. Maybe some other developer here who needs this could do some research and share his solution within this thread...
The JAR should be imported to the plugin and placed under the lib/ directory. After this you should be able to do grails clean, grails compile and grails package-plugin.
If you want to replace the log implementation, as I did, you should exclude the grails-logging and grails-plugin-log4j JARs from your designated project's classpath. This is done in the BuildConfig.groovy file:
inherits("global") {
excludes "grails-plugin-log4j", "grails-logging"
}
Now install your plugin grails install-plugin \path\to\plugin.zip and everthing should work as expected.
Hope this helps...

Java "NoSuchMethodError"

I'm getting:
NoSuchMethodError: com.foo.SomeService.doSmth()Z
Am I understanding correctly that this 'Z' means that return type of doSmth() method is boolean? If true, then that kind of method really does not exist because this method returns some Collection. But on the other hand if I call this method, I'm not assigning its return value to any variable. I just call this method like this:
service.doSmth();
Any ideas why this error occurs? All necessary JAR files exist and all other methods from this class seems to exist.
Looks like method exists in classpath during compilation, but not during running of your application.
I don't think return type is a problem. If it was, it wouldn't compile. Compiler throws error when method call is ambiguous, and it is when two methods differ only by return type.
Normally, this error is caught by the compiler; this error can only occur at run time if the definition of a class has incompatibly changed.
In short - a class/jar file at runtime is not the same that you used at compile time.
This is probably a difference between your compile-time classpath and you run-time classpath.
Here is what seems to be going on:
The code is compiled with a class path that defines the doSmth() method returning a boolean. The byte-code refers to the doSmth()Z method.
At runtime, the doSmth()Z method isn't found. A method returning a Collection is found instead.
To correct this problem, check your (compile time) classpath.
The current reply just tell you why is failing. Usually is even nicer to know how to fix problems. As it is mentioned, the problem usually is that you built your program but when running or exporting it, the library is not included. So the solution is...
If you are running, check the the run configuration
Select Run tab -> Run configurations -> Select the configuration you are running -> Check the Classpath tab -> Ensure the libraries you need are there
If you are exporting (for example a war file), follow this
Select project -> Select properties -> Select Deployment Assembly -> Press Add -> Select Java Build Path Entries -> Select the libraries you want to be included in your exported file (for example a war file)
In both cases, ensure the library which you are referencing in included.
Other frequent problems for this error are not the right type of parameters or visibility but then, the compiler will detect the error before running. In this case, just check the documentation to match the function and package visibility, and ensure that the library is found in Java Build Path in your project properties.
Maybe still can help somebody, but this exception can happen also when you have on the classpath two classes in different jar files that have the same exact signature but they haven't the same public methods.
For example:
On file mylibrary1.jar you have class com.mypackage.mysubpackage.MyClass with method doSmth()
On file mylibrary2.jar you have class com.mypackage.mysubpackage.MyClass without method doSmth()
When searching the class, the classloader may find first mylibrary2.jar depending on the path precedence but can't find the method on that class.
Be sure you don't have the same package + class on two different files.
I noticed this problem occurring while testing some experimental changes in multiple linked projects, after updating them from SVN in Eclipse.
Specifically, I updated all projects from SVN, and reverted the .classpath file rather than edit it manually to keep things simple.
Then I re-added the linked projects to the path, but forgot to remove the related jars. This was how the problem occurred for me.
So apparently the run time used the jar file while the compiler used the project files.
Another way this can happen and is difficult to find:
If a signature of a method in an external jar changes in a way that there is no error found in the IDE because it's still compatible with how you call it the class might not be re-compiled.
If your build checks the files for changes and only then recompiles them, the class might not be recompiled during the build process.
So when you run it this might lead to that problem. Although you have the new jar, your own code expects still the old one but does never complain.
To make it harder it depends on the jvm if it can handle such cases. So in the worst case it runs on the test server but not on the live machine.

Hibernate in Servlet causesNoClassDefFoundError: org/slf4j/LoggerFactory

I have a Java (6) application which uses Hibernate (V3.3.2) to read data from HSQLDB, which i build and debug/run with Eclipse (V3.5.1), and it works fine.
I then created a GWT (V1.7) Servlet web app, copied my hibernate classes into it, and added the same User Libraries dependencies. However when i run the servlet and try to access a URL which invokes my code i get this:
java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
at org.hibernate.cfg.Configuration.<clinit>(Configuration.java:152)
at xxx.daoimpl.DAOSession.initialise(DAOSession.java:40)
where DAOSession.java:40 is :
AnnotationConfiguration config = new AnnotationConfiguration ();
Googling for this error suggests i am missing slf4j-api.jar from the classpath, however if i look at the command line for the Debug properties i can see this jar there:
C:\java\jsedk_6\jre\bin\javaw.exe
-agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:54541
-Xmx512m -Dfile.encoding=Cp1252
-classpath
D:\dev\workspace\xxx\src;
D:\dev\workspace\xxx\resources;
D:\dev\workspace\xxx\war\WEB-INF\classes;
C:\java\eclipse\plugins\com.google.gwt.eclipse.sdkbundle.win32_1.7.1.v200909221731\gwt-windows-1.7.1\gwt-user.jar;
C:\java\eclipse\plugins\com.google.gwt.eclipse.sdkbundle.win32_1.7.1.v200909221731\gwt-windows-1.7.1\gwt-dev-windows.jar;
C:\java\hibernate-annotations-3.4.0.GA\hibernate-annotations.jar;
C:\java\hibernate-annotations-3.4.0.GA\lib\ejb3-persistence.jar;
C:\java\hibernate-annotations-3.4.0.GA\lib\hibernate-commons-annotations.jar;
C:\java\hibernate-distribution-3.3.2.GA\hibernate3.jar;
C:\java\hibernate-distribution-3.3.2.GA\lib\required\antlr-2.7.6.jar;
C:\java\hibernate-distribution-3.3.2.GA\lib\required\commons-collections-3.1.jar;
C:\java\hibernate-distribution-3.3.2.GA\lib\required\dom4j-1.6.1.jar;
C:\java\hibernate-distribution-3.3.2.GA\lib\required\javassist-3.9.0.GA.jar;
C:\java\hibernate-distribution-3.3.2.GA\lib\required\jta-1.1.jar;
C:\java\hibernate-validator-4.0.1.GA\hibernate-validator-4.0.1.GA.jar;
C:\java\hibernate-validator-4.0.1.GA\lib\validation-api-1.0.0.GA.jar;
C:\java\hibernate-validator-4.0.1.GA\lib\log4j-1.2.14.jar;
C:\java\hsqldb\lib\hsqldb.jar;
C:\java\restlet-jse-2.0m5\lib\org.restlet.jar;
C:\java\restlet-jee-2.0m5\lib\org.restlet.ext.servlet.jar;
C:\java\restlet-jse-2.0m5\lib\org.restlet.ext.xml.jar;
C:\java\slf4j-1.5.8\slf4j-api-1.5.8.jar;
C:\java\slf4j-1.5.8\slf4j-log4j12-1.5.8.jar
com.google.gwt.dev.HostedMode
...
If i open the jar i can see the LoggerFactory class in there.
Any idea why it isn't being found by the class loader?
Edit 1: If try to access org.slf4j.LoggerFactory from my code, Eclipse compiles it ok, but i get the same error at runtime.
Edit 2: If i add a Test class with a main which calls the same code and run it, it works. So this classpath problem seems specific to the Servlet.
thanks,
jon
It seems that copying the two slf4j jars to the war/WEB-INF/lib sub-project/dir fixed the problem. I'm not really sure why i should need to do this for these two jars and not for all the other Hibernate, Restlet etc jars that the project also uses, though i suppose for consistency i will do that anyway - i guess it will make deployment easier as well.
If someone can provide some sort of explanation as to why this worked and why exactly i need to do it i will select it as the "correct" answer, otherwise i'll select this one.
Can you please reconfirm that you have at least two slf4j.jar files in the classpath, the slf4j-api.jar and exactly one implementation, such as slf4j-jdk14.jar?
You must not have multiple sflj4-implementations in the classpath.
You have a runtime dependency issue so everything compiles fine but the dependency is in your jars. You need to visit the Hibernate site and look at the compatibility matrix and make sure you are matched up correctly then check the dependencies for annotations and core. You log4J jars look fine so it's definitely some quirk.
If it works in Eclipse then logically it's definitely some diff between the 2 runtimes (eclipse and non-eclipse), if the matrix checks out fine then see if you can factor out the commonalities in the 2 then work out the differences -- your answer should be in there.
I had a similar issue except I was using Tomcat and the NoClassDefFound error was on the juli logger. I fixed it by removing the Tomcat dependencies from my classpath when running in hosted mode because hosted mode embeds a Tomcat server that was conflicting. So I would see what happens if you remove some or all of the restlet jars from your classpath to see if they conflict.

Categories

Resources