1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.ksb.util;
17
18 import org.apache.log4j.Logger;
19 import org.apache.xml.security.algorithms.SignatureAlgorithm;
20 import org.kuali.rice.core.framework.util.ApplicationThreadLocal;
21 import org.springframework.beans.BeansException;
22 import org.springframework.context.ApplicationContext;
23 import org.springframework.context.ApplicationContextAware;
24 import org.springframework.context.ApplicationListener;
25 import org.springframework.context.ConfigurableApplicationContext;
26 import org.springframework.context.event.ContextClosedEvent;
27
28 import java.lang.reflect.Field;
29 import java.util.ArrayList;
30 import java.util.Collection;
31
32
33
34
35 public class SignatureAlgorithmCacheCleaner implements ApplicationContextAware {
36 private static final Logger LOG = Logger.getLogger(SignatureAlgorithmCacheCleaner.class);
37
38
39
40
41
42 @Override
43 public void setApplicationContext(ApplicationContext applicationContext) {
44
45 if (applicationContext instanceof ConfigurableApplicationContext) {
46 ConfigurableApplicationContext context = (ConfigurableApplicationContext) applicationContext;
47 context.addApplicationListener(new ApplicationListener<ContextClosedEvent>() {
48 @Override
49 public synchronized void onApplicationEvent(ContextClosedEvent e) {
50 LOG.info("Context '" + e.getApplicationContext().getDisplayName() + "' closed, removing SignatureAlgorithm caches");
51
52
53 String[] threadLocalFields = new String[] { "instancesSigning", "instancesVerify", "keysSigning", "keysVerify" };
54 Collection<ThreadLocal> threadLocals = new ArrayList<ThreadLocal>(threadLocalFields.length);
55 for (String fname: threadLocalFields) {
56 try {
57 Field f = SignatureAlgorithm.class.getDeclaredField(fname);
58 if (f != null) {
59 f.setAccessible(true);
60 ThreadLocal tl = (ThreadLocal) f.get(null);
61 if (tl != null) {
62 threadLocals.add(tl);
63 }
64 }
65 } catch (NoSuchFieldException nsme) {
66 nsme.printStackTrace();
67 } catch (IllegalAccessException iae) {
68 iae.printStackTrace();
69 }
70 }
71
72
73 if (!threadLocals.isEmpty()) {
74 for (Thread t: Thread.getAllStackTraces().keySet()) {
75 for (ThreadLocal tl: threadLocals) {
76 ApplicationThreadLocal.removeThreadLocal(t, tl);
77 }
78 }
79 }
80 }
81 });
82 }
83 }
84 }