Illegal Access in WebappClassLoader.loadClass - java

I have a task scheduler implemented in my application. Basically, what i do is schedule some task's to be executed 4 times in a day (like 6 in 6 hours), so the system schedules it to: 00:00, 06:00, 12:00, 18:00.
Ok, i have a class (FlowJobController) which extends the Thread class and in the run() implementation i keep sleeping the thread in 60 to 60 seconds, so it's executed again to check if there's any task to be executed. If true, i run my Job.
Basically the main part it:
rSet = pStmt.executeQuery();
while (rSet.next()) {
long jobId = rSet.getLong("trf_codigo");
String ruleName = rSet.getString("reg_nome");
String ruleParameters = rSet.getString("trf_regra_parametros");
Job job = new Job();
job.setId(jobId);
job.setRuleName(ruleName);
job.setParameters(Functions.stringToList(ruleParameters, "\n"));
FlowJob flowJob = new FlowJob(this, job);
flowJob.start();
}
} catch (Exception ex) {
logger.error(WFRSystem.DEFAULT_USER, system.getCode(), ex);
} finally {
try {
DBConnection.close(pStmt);
DBConnection.close(rSet);
// executede 60 in 60 sec
Thread.sleep(60 * 1000);
} catch (InterruptedException ex) {
logger.error(WFRSystem.DEFAULT_USER, system.getCode(), ex);
}
}
The thing is: When the pStmt.executeQUery() returns records to be executed, it goes into the while and the error appears into the line: Job job = new Job();
The error is:
Exception in thread "FlowJobController" java.lang.NoClassDefFoundError: wfr/com/Job
at wfr.com.FlowJobController.run(FlowJobController.java:112)
Before this error i got this error:
25/09/2012 12:00:09 org.apache.catalina.loader.WebappClassLoader loadClass
INFO: Illegal access: this web application instance has been stopped already. Could not load wfr.com.Job.
The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
java.lang.IllegalStateException
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1566)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1526)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at wfr.com.FlowJobController.run(FlowJobController.java:112)
The FlowJobController.java:112 is the Job job = new Job();
What am i doing wrong?

The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
If you are saying that your code deliberately threw the IllegalStateException exception, then that is the likely cause of the subsequent problems. If you throw an uncheck exception in static initialization, and that exception propagates, then the class initialization fails, and the class (and all classes that depend on it) are unusable. In this case, it looks like it also caused the webapp to be stopped.
If this is the problem, the solution is "don't do that". Fix whatever is causing the exception to be thrown.
The other possibility is that this is simply a missing class problem:
Well, that sounds not possible (to not be in the war) since i'm running into the eclipse environment and it's in the class folder directory and no errors is shown about not finding those classes...
The class loader won't be looking in the Eclipse classes folder. It will be looking in the webapp directory on your web container (Tomcat, Jetty, whatever).

Related

Synchronous and Asynchronous exceptions in Java

While reading jvm specification I came across exception (2.10 Exceptions)
Most exceptions occur synchronously as a result of an action by the
thread in which they occur. An asynchronous exception, by contrast,
can potentially occur at any point in the execution of a program ...
What are the differences between the two types ?
Keeping reading, the specification gives and example of an asynchronous exception
An asynchronous exception occurred because: – The stop method of class
Thread or ThreadGroup was invoked, or – An internal error occurred in
the Java Virtual Machine implementation.
But what makes stop method of a class thread special in this regard ?
Can you explain the differences between the two and give some examples of them, other than the given ones ?
The stop method can be called from another thread which could leave the data altered by the thread stopped in an inconsistent state.
For this reason Thread.stop() is being removed. I suggest you not use it.
Can you explain the differences between the two and give some examples of them, other than the given ones
The difference is that an asynchronous exception is triggered by another thread at any point in the code.
They should not happen under normal operation.
A specific implementation of the JVM could have other errors but there is not exhaustive list.
There isn't much you can do about except shutdown gracefully.
Here's an example showing the two types of exception. Consider the following code snippets, which show the two kinds of exception being raised, and handled:
public static void main(String[] args) throws Exception {
try {
syncException();
} catch (RuntimeException re) {
System.out.println("-1-");
re.printStackTrace();
}
CompletableFuture<Void> f = null;
try {
f = asyncException();
} catch (RuntimeException ex) {
System.out.println("-2-" + Thread.currentThread().getName());
ex.printStackTrace();
}
try {
f.get();
} catch (Exception ex) {
System.out.println("-3-");
ex.printStackTrace();
}
}
A synchronous exception
private static void syncException() {
throw new RuntimeException("Sync exception #" + Thread.currentThread().getName());
}
And an asynchronous exception - raised in a different thread from the calling code:
private static CompletableFuture<Void> asyncException() {
return CompletableFuture.runAsync(() -> {
throw new RuntimeException("Async exception #" + Thread.currentThread().getName());
}, Executors.newFixedThreadPool(1));
}
Now, when that code is executed, the following stack traces are produced:
The synchronous exception's stack trace:
-1-
java.lang.RuntimeException: Sync exception #main
at stackoverflow.Main.syncException(Main.java:34)
at stackoverflow.Main.main(Main.java:11)
Note that -2- was not printed, because the exception was asynchronous. See the third catch block's stack trace for how asynchronous exceptions are handled. Note that the thread in which the exception was raised is different from the one printing the stack trace:
-3-
java.util.concurrent.ExecutionException: java.lang.RuntimeException: Async exception #pool-1-thread-1
at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895)
at stackoverflow.Main.main(Main.java:26)
Caused by: java.lang.RuntimeException: Async exception #pool-1-thread-1
at stackoverflow.Main.lambda$0(Main.java:39)
at java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1626)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
An asynchronous exception, by contrast, can potentially occur at any point in the execution of a program ...
Just a comment on this: you'll notice that the code in thread pool-1-thread-1 could raise the exception any time of the main thread's execution. This is probably relative among threads. But in this example, the main thread being the main programe execution, we can say that the "Async exception #pool-1-thread-1" exception occurred asynchronously.

How to catch exception from external jar in Java

I'm try to run LDA algorithm using mallet library. When I try to run LDA with a set of parameters it's OK but with another set I have this error:
09-Oct-2014 23:50:24.354 INFO [http-nio-8084-exec-127] cc.mallet.topics.ParallelTopicModel.estimate <50> LL/token: -8.73265
09-Oct-2014 23:50:24.657 INFO [http-nio-8084-exec-127] null.null [beta: 0.00795]
09-Oct-2014 23:50:24.657 INFO [http-nio-8084-exec-127] null.null <60> LL/token: -8.6299
09-Oct-2014 23:50:24.957 INFO [http-nio-8084-exec-127] cc.mallet.topics.ParallelTopicModel.estimate <70> LL/token: -8.61982
09-Oct-2014 23:50:25.019 INFO [http-nio-8084-exec-127] null.null [beta: 0.00583]
09-Oct-2014 23:50:25.263 INFO [http-nio-8084-exec-127] cc.mallet.topics.ParallelTopicModel.estimate <80> LL/token: -8.89656
09-Oct-2014 23:50:25.402 INFO [http-nio-8084-exec-127] null.null [beta: 0.00484]
java.lang.ArrayIndexOutOfBoundsException: -1 at
cc.mallet.topics.WorkerRunnable.sampleTopicsForOneDoc(WorkerRunnable.java:489) at
cc.mallet.topics.WorkerRunnable.run(WorkerRunnable.java:275) at
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at
java.util.concurrent.FutureTask.run(FutureTask.java:266) at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at
java.lang.Thread.run(Thread.java:745) java.lang.ArrayIndexOutOfBoundsException: -1 at
cc.mallet.topics.WorkerRunnable.sampleTopicsForOneDoc(WorkerRunnable.java:489) at
cc.mallet.topics.WorkerRunnable.run(WorkerRunnable.java:275) at
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at
java.util.concurrent.FutureTask.run(FutureTask.java:266) at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at
java.lang.Thread.run(Thread.java:745)
My code look like:
try{
//call some function from library
} catch(Exception e){
System.out.println("LDA Exception")
}
How can catch exception caused by external jars? I have reed this question but it doesn't work for me. Any Idea?
EDIT:
My project is an restful webservice which it run on apache tomcat Server. I try to call lda algorithm in dopost function.
EDIT 2
Mallet is an open source library. So I tried to read code and I found the below code.
public class ParallelTopicModel implements Serializable {
int numThreads = 2;
public void estimate() throws IOException {
WorkerRunnable[] runnables = new WorkerRunnable[numThreads];
for (int thread = 0; thread < numThreads; thread++) {
runnables[thread] = new WorkerRunnable(numTopics, alpha, alphaSum, beta,
random, data, runnableCounts,
runnableTotals, offset, docsPerThread);
//some code
}
}
}
public class WorkerRunnable implements Runnable {
public void run() {
try {
//some code
} catch (Exception e) {
e.printStackTrace();
}
}
}
My webservice:
#POST
#Produces("application/xml")
public String getXml(#FormParam("xmlinput") String xmlinput) throws Exception {
try {
//call estimate function in ParallelTopicModel class
//return an xml;
} catch (Exception e) {
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<modelingOutput>null</modelingOutput>";
}
So how can handle exceptions whiche produce WorkRunnable class in my web service. I want to ruturn an xml look like
`null
I have read a lot of questions like this and this but I don't found solution
The problem here is not that the call is to an external jar. Exceptions thrown by any method in your chain of calls, no matter where the actual class's bytecode is stored, are caught at the first catch block up the chain.
The problem you have here is that the exception occurs in a different thread. If you start a separate thread from your code, the exceptions in that thread are not passed on to your thread. As far as your code is concerned, that call has completed. If the code in the other thread doesn't catch them, they'll be caught by that thread's exception handler, if there is such a handler.
Runtime errors are usually caused by bad input, so the usual strategy to avoid them would be to understand why your parameters cause the array index in that method to be negative, and then make sure you never pass such parameters to that method.
If that is impossible, you may create an exception handler for the thread. This would work only if you are the one in control of creating the thread and you can set the handler in it.
You may want to look at this question for more about handling exceptions in threads.
Edit:
Since their WorkerRunnable code seems to catch all exceptions (and print a stack trace), there is no way to catch them yourself. You can do one of two things:
As I said above, check what parameters you passed caused the array out of bounds error, and avoid those conditions. Use an if statement and if the parameters are bad, print your <modelingOutput>null</modelingOutput> output - without running the modeling in the first place.
Use their source, change their catch clause to something that sets a variable that tells you there was an exception, compile it and use that jar instead of theirs. That's what Open Source is for. You may want to communicate with the maintainers of that library and tell them that it would be nice if they added a way to detect if an exception was caused by one of the sub threads.

WebService times out, but client receives no exception

I have an application that is attempting to call a service and the other service appears to be timing out. The problem is my application does not receive any timeout exceptions, although I do see an error printed out to the console:
[7/8/13 12:39:32:360 EDT] 00000005 TimeoutManage I WTRN0006W: Transaction 0000013FBF252E43000000010000000CE81CB4935851D5C13DECD3DBB2D463F0DBECAEE60000013FBF252E43000000010000000CE81CB4935851D5C13DECD3DBB2D463F0DBECAEE600000001 has timed out after 120 seconds.
[7/8/13 12:39:32:360 EDT] 00000005 TimeoutManage I WTRN0124I: When the timeout occurred the thread with which the transaction is, or was most recently, associated was Thread[WebContainer : 1,5,main]. The stack trace of this thread when the timeout occurred was:
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:196)
com.ibm.io.async.AbstractAsyncFuture.waitForCompletion(AbstractAsyncFuture.java:334)
com.ibm.io.async.AsyncFuture.getByteCount(AsyncFuture.java:218)
com.ibm.ws.tcp.channel.impl.AioSocketIOChannel.readAIOSync(AioSocketIOChannel.java:215)
com.ibm.ws.tcp.channel.impl.AioTCPReadRequestContextImpl.processSyncReadRequest(AioTCPReadRequestContextImpl.java:182)
com.ibm.ws.tcp.channel.impl.TCPReadRequestContextImpl.read(TCPReadRequestContextImpl.java:111)
com.ibm.ws.http.channel.outbound.impl.HttpOutboundServiceContextImpl.parseResponseMessageSync(HttpOutboundServiceContextImpl.java:1657)
com.ibm.ws.http.channel.outbound.impl.HttpOutboundServiceContextImpl.readSyncResponse(HttpOutboundServiceContextImpl.java:725)
com.ibm.ws.http.channel.outbound.impl.HttpOutboundServiceContextImpl.startResponseReadSync(HttpOutboundServiceContextImpl.java:1775)
com.ibm.ws.http.channel.outbound.impl.HttpOutboundServiceContextImpl.finishRequestMessage(HttpOutboundServiceContextImpl.java:1195)
com.ibm.ws.websvcs.transport.http.out.HttpOutSyncWriter.finishBufferRequest(HttpOutSyncWriter.java:94)
com.ibm.ws.websvcs.transport.http.out.HttpOutWriter.writeBuffer(HttpOutWriter.java:136)
com.ibm.ws.websvcs.transport.http.out.HttpOutByteBufferOutputStream.finish(HttpOutByteBufferOutputStream.java:468)
com.ibm.ws.websvcs.transport.http.SOAPOverHTTPSender.sendChunkedRequest(SOAPOverHTTPSender.java:890)
com.ibm.ws.websvcs.transport.http.SOAPOverHTTPSender.sendSOAPRequest(SOAPOverHTTPSender.java:807)
com.ibm.ws.websvcs.transport.http.SOAPOverHTTPSender.send(SOAPOverHTTPSender.java:611)
com.ibm.ws.websvcs.transport.http.HTTPTransportSender.invoke(HTTPTransportSender.java:364)
org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:531)
org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:401)
org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:228)
org.apache.axis2.client.OperationClient.execute(OperationClient.java:163)
org.apache.axis2.jaxws.core.controller.impl.AxisInvocationController.execute(AxisInvocationController.java:581)
org.apache.axis2.jaxws.core.controller.impl.AxisInvocationController.doInvoke(AxisInvocationController.java:130)
org.apache.axis2.jaxws.core.controller.impl.InvocationControllerImpl.invoke(InvocationControllerImpl.java:93)
org.apache.axis2.jaxws.client.proxy.JAXWSProxyHandler.invokeSEIMethod(JAXWSProxyHandler.java:364)
org.apache.axis2.jaxws.client.proxy.JAXWSProxyHandler.invoke(JAXWSProxyHandler.java:185)
The client is created with these settings:
bindProvider.getRequestContext().put(com.ibm.wsspi.webservices.Constants.RESPONSE_TIMEOUT_PROPERTY , connectionProperties.getProperty(MyService.TIME_OUT));
bindProvider.getRequestContext().put(com.ibm.wsspi.webservices.Constants.CONNECTION_TIMEOUT_PROPERTY , connectionProperties.getProperty(MyService.TIME_OUT));
bindProvider.getRequestContext().put(com.ibm.wsspi.webservices.Constants.READ_TIMEOUT_PROPERTY , connectionProperties.getProperty(MyService.TIME_OUT));
MyService.TIME_OUT has a value of 20000 and I have verified that it is being set correctly.
The code that catches calls the service looks like this:
try
{
response = ((MyServicePortType) myService).doWebServiceOperation(request);
}
catch (Throwable e) //I know, catch Throwable is not very good but right now I'd be happy to catch ANYthing here!
{
log.error("Webservice reported error",e);
}
Even though I've changed my catch block to catch anything, I still don't catch any exceptions. WebSphere detects a transaction timeout, but I don't know why the application doesn't detect a timeout in the web service call. Is there something I'm missing that would cause a proper timeout exception to be thrown so that I can catch it and send the message to the application framework?
Well now I feel silly.
It seems that for WebSphere, these properties (RESPONSE_TIMEOUT_PROPERTY, CONNECTION_TIMEOUT_PROPERTY, etc...) should have their values set in seconds, and I was using milliseconds based on what I'd seen in online examples (that clearly were not intended for WebSphere).
Changing 20000 to 20 has resolved this problem.
The page that suggested I should be assuming seconds instead of milliseconds is this one: http://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/rwbs_httptransportprop.html

Catched ActivitiException still gets thrown and breaks application

I'm having trouble understanding what is happening and why my loop doesn't continue. I'm creating a dashboard for all open activiti tasks. Now the trouble i am having is when someone closes a task while the dashboard is being created.
The code is like this:
List<Task> approvalTasks = taskQueryApproval.list();
for (Task task : approvalTasks) {
try {
ActivitiApplicationRequest activitiRequest = (ActivitiApplicationRequest) taskService
.getVariable(task.getId(), ACTIVITIREQUEST);
if (!dashboardValues.containsKey(activitiRequest.getGlobalRequestId())) {
GlobalRequest globalRequest = globalRequestDao
.findMinimalGlobalRequestForDashboardBySyscode(activitiRequest.getGlobalRequestId());
if (globalRequest != null) {
DashboardValueObject vo = new DashboardValueObject(globalRequest);
vo.setHasApproval(true);
dashboardValues.put(activitiRequest.getGlobalRequestId(), vo);
}
}
} catch (ActivitiException ex) {
LOGGER.debug("Approval already done, skipping activititask");
}
}
The trouble I'm having is I know when the task doesn't exist Activiti is going to throw an exception, that's why I placed a try-catch inside the for loop.
What I'm expecting is that when the error is catched it just continues with the rest of the list. While debugging I even saw the catch being done. But the loop still breaks and the application stops. With these exceptions :
SEVERE: Error while closing command context org.activiti.engine.ActivitiException: task 203039 doesn't exist
at org.activiti.engine.impl.cmd.GetTaskVariableCmd.execute(GetTaskVariableCmd.java:55)
at org.activiti.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:24)
at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:42)
9-nov-2012 14:45:42 org.activiti.engine.impl.interceptor.CommandContext close
SEVERE: Error while closing command context
org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: com.atomikos.jdbc.AtomikosSQLException: The transaction has timed out - try increasing the timeout if needed
### The error may exist in org/activiti/db/mapping/entity/Task.xml
### The error may involve org.activiti.engine.impl.persistence.entity.TaskEntity.selectTask
### The error occurred while executing a query
### SQL: select * from ACT_RU_TASK where ID_ = ?
### Cause: com.atomikos.jdbc.AtomikosSQLException: The transaction has timed out - try increasing the timeout if needed
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:8)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:81)
What am I doing wrong?

Illegal access (Quartz with JBoss)

I am running a scheduled job in a web application which sometimes (could notreproduce it ) results in the following exception:
[WebappClassLoader] Illegal access: this web application instance has been stopped already. Could not load org.quartz.StatefulJob. The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
java.lang.IllegalStateException
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1244)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1204)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at org.quartz.JobDetail.class$(JobDetail.java:279)
at org.quartz.JobDetail.isStateful(JobDetail.java:425)
at org.quartz.simpl.RAMJobStore.triggerFired(RAMJobStore.java:1313)
at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:342)
13:41:00,083 ERROR [STDERR] Exception in thread "DefaultQuartzScheduler_QuartzSchedulerThread"
13:41:00,083 ERROR [STDERR] java.lang.NoClassDefFoundError: org.quartz.StatefulJob
13:41:00,083 ERROR [STDERR] at org.quartz.JobDetail.class$(JobDetail.java:279)
13:41:00,083 ERROR [STDERR] at org.quartz.JobDetail.isStateful(JobDetail.java:425)
13:41:00,083 ERROR [STDERR] at org.quartz.simpl.RAMJobStore.triggerFired(RAMJobStore.java:1313)
13:41:00,083 ERROR [STDERR] at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:342)
There also a NoClassDefFoundError. It says that org.quartz.StatefulJob is not found.
Here is how the job is scheduled:
Scheduler sched = StdSchedulerFactory.getDefaultScheduler();
if (!sched.isStarted()){
sched.start();
}
String konf = MyConfigClass.getRow(25).getKonfiguration();
Calendar cal = Calendar.getInstance();
cal.setTime(MyParser.stf.parse(konf));
String expression = "0 " + cal.get(Calendar.MINUTE) + " " + cal.get(Calendar.HOUR_OF_DAY) + " ? * MON-FRI";
CronTrigger ct = new CronTrigger(triggerName, group, jobName, group, expression);
if (sched.getTrigger(triggerName, Scheduler.DEFAULT_GROUP) != null) {
sched.rescheduleJob(triggerName, group, ct);
} else {
JobDetail jd = new JobDetail(jobName, group, MyJob.class);
sched.scheduleJob(jd, ct);
}
I do not know what could be the problem. First I thought that the session dies before the job executes, but I've tried it and that's no the case. The interesting thing is that after this exception, the job runs again with no problem.
Do you have any ideas?
It looks like your quartz job is trying to do something after your app was stopped. It might be trying to access some resources that were available while your app was running, but not anymore (something like getResourceAsStream maybe).
It might help if you post more info: stacktraces, code of your job, etc.
After update:
Here is what I think is happening:
You schedule your job successfully
For whatever reason your webapp is stopped. I would search JBoss logs for a reason.
At this moment time comes to execute your job (org.quartz.simpl.RAMJobStore.triggerFired(RAMJobStore.java:1313))
This call goes down to isStateful method of JobDetail class
The method has this code in it return (StatefulJob.class.isAssignableFrom(jobClass));
StatefulJob class was not loaded before. Your classLoader tries to load it (org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1204))
Since your webapp was stopped, you are getting exception
The way I see it, you have two choices:
Ignore this problem, since there is nothing you can do to make quartz work after your webapp was stopped
Try to figure out what causes your webapp to stop and fix it

Categories