https://stackoverflow.com/a/5948326/9454856
Exception in thread "main" java.lang.AbstractMethodError: org.apache.xerces.dom.CoreDOMImplementationImpl.createLSSerializer()Lorg/w3c/dom/ls/LSSerializer;
Why am I getting this error?
The definition of AbstractMethodError says:
Thrown when an application tries to call an abstract method. Normally, this error is caught by the compiler; this error can only occur at run time if the definition of some class has incompatibly changed since the currently executing method was last compiled.
So you've got some kind of configuration or version control problem in your code, probably you're picking up a different version of Apache Xerces at run time from the version used at compile time; though it also suggests you might be straying outside the stable API into calling methods that weren't really intended for public use.
As I can't see your code, there's a lot of guesswork here. The next stage in debugging would be to look at a stack trace.
We have some builds that are failing with variations of this error:
Error creating bean with name 'cartServiceImpl': Unsatisfied dependency expressed through field 'addressServiceClient'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'addressServiceClient': Bean with name 'addressServiceClient' has been injected into other beans [addressInfoServiceImpl] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.
The thing is, we never see this error when we start up the service on our desktops. We only see this error when the build runs on the CI server. In fact, most of the time when we're building the same code, this error does not occur. I have a test case where it runs four concurrent builds of the same branch and commit (targeting for deployment to four different clusters), and sometimes all four succeed, but sometimes one (or even two) of them will fail with this error.
My first theory, when I determined the seeming randomness of this, was that there was some screwy problem with our docker registry or docker cache, which was somehow occasionally giving us an older image (there was a related problem of this nature, for real, several weeks ago). Despite my desire to hang this on another team, I have to assume that there's something we're doing that could be causing this, but perhaps it's random because this is depending on a race condition. I find it hard to believe that Spring bean resolution could have race conditions.
Is there any possibility that an error like this might occur or not occur, depending on race conditions?
We're using Spring Framework 5.0.9 with Spring Boot 2.0.5.
Update:
Note that I still can't repeat this problem with ordinary testing on my laptop, but we were able to extract the jar file constructed on the CI server and download it to my laptop, and then run that directly, and it does get the same error. We compared the contents of the jar file between that jar and a "good" one, and the differences were subtle, no obvious problems that might cause this. We did notice that the AddressServiceClient mentioned in the error is second in the list of classes in the "bad" jar, and far down the list in the "good" jar.
I then thought that perhaps adding #Lazy to the AddressServiceClient class would avoid the problem (not that I don't say "fix"). I tried modifying that "bad" jar file locally, using "zip" to update the jar file with the updated class file, and I found that that resulting jar file did NOT demonstrate the symptom. However, when I finally merged the PR with this change and the builds ran on the CI server, one of them still failed with the same error.
You can use setter injection, it use Spring L3 Cache.
For example:
private TmsOrderService tmsOrderService;
#Autowired
public void setTmsOrderService(TmsOrderService tmsOrderService) {
this.tmsOrderService = tmsOrderService;
}
Spring L3 Cache avoid circular dependencies.
I am Getting this error when trying to run spring batch to load the list of executions.
java.lang.IllegalAccessError: tried to access method
org.springframework.batch.core.repository.dao.JdbcJobExecutionDao.getJobParameters(Ljava/lang/Long;)Lorg/springframework/batch/core/JobParameters;
from class
org.springframework.batch.admin.service.JdbcSearchableJobExecutionDao
After doing some analysis, I found that JdbcJobExecutionDao is part of Spring-batch and has the implementation of getJobParameters() as protected method while, JdbcSearchableJobExecutionDao is part of spring-batch-admin which has extended the JdbcJobExecutionDao.
So as per the Oracle documentation, it says that IllegalAccessError is -
Thrown if an application attempts to access or modify a field or to
call a method that it does not have access to.
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.
I don't understand, I don't have control over these jars/classes. Am I doing something wrong while using them? or is there a problem with the versions I am using for both jars.
spring-batch - version 2.2.0.RELEASE
spring-batch-admin - version 1.3.0.BUILD-SNAPSHOT(Tried with 1.3.0.RELEASE also)
Refered to sites -
java.lang.IllegalAccessError: tried to access method
https://github.com/spring-projects/spring-batch/blob/master/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDao.java
https://github.com/spring-projects/spring-batch-admin/blob/master/spring-batch-admin-manager/src/main/java/org/springframework/batch/admin/service/JdbcSearchableJobExecutionDao.java
So, I fixed this by using proper versions. It was a version mismatch problem between spring-batch & spring-batch-admin. I referred to this spring docs site and tried the recommended versions and it worked!
http://docs.spring.io/spring-batch-admin/spring-batch-admin-manager/dependencies.html
So, now I am using
2.2.7.RELEASE(Spring-Batch)
with
1.3.1.RELEASE(Spring-Batch-Admin)
and I am not getting the java.lang.IllegalAccessError anymore. Need to check if any other functionalities have been disturbed because this is a very old project.
Hope this helps someone facing similar problem.
Is there a way to be notified of caught exceptions in an eclipse application?
I know that if I start an application using eclipse debugger, I can suspend execution upon caught and uncaught exceptions (see https://stackoverflow.com/a/3066280/228965). I guess this feature somehow uses JVMTI.
Now I have the following problem:
I have an eclipse application not written by me. I want to monitor this application. I have written some bundles to monitor different aspect of the application (user interactions, workbench changes, etc..). I start these bundles along the application using bundles.info file. Now I need to be notified whenever an exception happens. I added a listener to error log and this way I am notified of uncaught exceptions. However I want also to be able to be notified of "any" exception, even those that have been caught by the original developers.
Is there a way to achieve this?
You could investigate the logger of your application. If it use log4j, you could create an appender specific for exceptions and work with them.
Add a breakpoint to the constructors of java.lang.Exception (or maybe even Throwable, depending upon exactly what you're looking for).
All exceptions, even custom ones, must extend from one of these, so you can find each Exception as it is being created - and then even trace it through to see where it is being caught and handled (if at all).
Using AOP may also be a good option, but this approach doesn't require any modifications to the existing code - source code or byte code.
From JDK 1.5 you can use Thread.setDefaultUncaughtExceptionHandler() for exactly this purpose.
I have a new puzzle for you :-).
I was thinking on how should an application handle his own start up. Like : checking for required libraries, correct versions, database connectivity, database compatibility, etc. To be specific, here is the test case. I use SWT and Log4J, for obvious reasons. Now, the questions :
Should the app check itself for the required dependencies? If yes, should the user be given specific details of what it's missing? Or just a message, and details to the logs?
What if the log4J library is unavailable?
What is the best to do the test? Verifying the file existance (using file.exists(), at specified path), or loading a class, say Class.forName("org.apache.log4j.Logger")? What should be the proper order to do the checks? For instance, if i test for SWT, i have no idea if logger is available or not, and the error will occur when i try to access that. Backwards, if i test for the logger 1st : a) The lib could be unavailable - i cannot log the error; b) SWT could be unavailable - unable to display the user message.
I've discovered apache.commons.lang framework today, and i find very useful the method org.apache.commons.lang.SystemUtils.isJavaVersionAtLeast(Float value)
, and manny others, i am sure. However, importing too much libs to your project dont make it hard to maintain? Versions change, compatibilities are lost, eg. one cannot control a 3rd party developement style or direction.
Thank u for your answers.
I agree with your need. Checking for required runtime environment provides:
immediate feedback, instead of randomly breaking when accessing some functionnality
hopefully more skilled user, as the immediate feedback is available to the guy that is installing the software, hopefully more skilled than an average user, or at least less confident (installing is always a special operation). A more skilled user is less disturbed if the error is coming in the console, he doesn't depend on a graphical interface.
improved reporting : the error message can be explicit (you're in charge), while default error messages come in many flavours (they are not always that helpful on 1. what's wrong 2. suggesting a fix).
But please note that the runtime requirements could be checked in two situations:
when installing : long verifications are always acceptable ; if a library is not here, a required database or WebService is not accessible, it won't be here at runtime either, so you can complain immediately.
when starting the execution : you can verify again (and some verifications may only happen at that point)
This suggests creating an installer for your application.
Potentially, errors would not all be blocking for the installation. Some would rather accumulate as a list of tasks to be done after installation, maybe nicely formatted in a file with all reference information.
Here, we once again hit the notion of error level in validation (similar to what happens for Log4j) : some validation errors are at fatal level, others are errors, possibly also warnings ...
In our projects, we have some sort of initialization and validation going on on startup. Based on our day-to-day experience, I would suggest the following:
When the application gets big, you don't want to have all init centralized in one class, so we have a modular structure.
A small kernel is configured with a list of modules classes. It's whole init sequence is under strict control, ready for any exceptions (translating them to appropriate messages, but memorizing the stack traces that are so useful to the developpers), making no assumption on the available libraries and so on... CheckStyle can be configured specially for this code.
The interface (of course, abstract class is possible) that the modules implement typically have several initialization methods. They could be:
getDependencies : returns a list of modules that this one depends on.
startup : when the whole application is starting. This will be called only once during startup, and cannot be called again.
start : when the module gets ready for regular operation
stop : reverse from start
shutdown : reverse from startup.
The kernel instanciates each of the module in turn. Then he calls one init method on all of them, then another init method and so on as needed. Each init method can:
signal error conditions (using levels, like Log4J).
an exception thrown would be caught by the kernel, and translated to an error condition
consult another module for its status (because dependencies are the general case), and react accordingly. If needed, the dependencies could be made declaratively.
The kernel takes care of module dependencies generically:
He sorts the modules so that dependencies are respected.
He doesn't initialize a module if one of its dependencies couldn't make it.
If asked to stop a module, he will first stop the modules that depends on it.
A nice feature of this kernel approach is that it is easy to aggregate the errors, at various levels (although fatal could stop it), and report all of them at the end, using whatever means is available (SWT or not, Log4J or not ...). So instead of discovering the problems one after the other, and having to start again each time, you could deliver in one blow (nicely prioritized of course).
Concerning your precise questions:
Should the app check itself for the required dependencies?
Yes (see higher)
If yes, should the user be given specific details of what it's missing? Or just a message, and details to the logs?
As said higher, when installing the user is more prepared to deal with this.
When starting, we use an easy message for the end-user, but give access to the full stack traces for the developper (we have a button that copies in the clipboard the application environment, the stack traces and so on).
What if the log4J library is unavailable?
Log without it (see higher).
What is the best to do the test? Verifying the file existance (using file.exists(), at specified path), or loading a class, say Class.forName("org.apache.log4j.Logger")?
I would load a class. But if it failed, I might check the file existence on disk to give a improved message, including "how to fix".
What should be the proper order to do the checks? For instance, if i test for SWT, i have no idea if logger is available or not, and the error will occur when i try to access that. Backwards, if i test for the logger 1st : a) The lib could be unavailable - i cannot log the error; b) SWT could be unavailable - unable to display the user message.
As I said higher, I suggest these low-level errors get accumulated in a small area of code (kernel), where you could use anything that is available to display them. If nothing is available, you could simply log in the console without Log4J.
The short answer is no. The JVM appropriately handles this functionality on initialization, or at runtime. If a required class is not found on the classpath, a ClassNotFoundException will be thrown. If a class was found, but a required method was not, a NoSuchMethodException is thrown.
Regarding 1 through 3 , there are 2 main use cases here:
application packaging is under your control, and can make sure that all required dependencies are packaged properly. Run-time validations are not useful here.
application packaging is not under your control, and you deliver the main jar and the instructions on what the requirements are. Run-time validations might be useful, but someone who wants to package your application usually has enough skill to understand what a ClassNotFoundException: org.apache.logging.LogManager means.
Regarding 4, as long as you keep the same version of the dependency included in your project, you will have no problems in keeping control. Upgrading to a newer version is a conscious decision, which requires thought and testing.