View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.servlet;
20  
21  import java.io.IOException;
22  import java.io.PrintStream;
23  import java.lang.reflect.InvocationTargetException;
24  import java.lang.reflect.Method;
25  import java.util.ArrayList;
26  import java.util.Arrays;
27  import java.util.Collection;
28  import java.util.Collections;
29  import java.util.HashMap;
30  import java.util.HashSet;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.Set;
34  import java.util.Stack;
35  
36  import javax.servlet.Servlet;
37  import javax.servlet.ServletConfig;
38  import javax.servlet.ServletContext;
39  import javax.servlet.ServletException;
40  import javax.servlet.ServletRequest;
41  import javax.servlet.ServletResponse;
42  import javax.servlet.SingleThreadModel;
43  import javax.servlet.UnavailableException;
44  
45  import org.eclipse.jetty.security.IdentityService;
46  import org.eclipse.jetty.security.RunAsToken;
47  import org.eclipse.jetty.server.Request;
48  import org.eclipse.jetty.server.UserIdentity;
49  import org.eclipse.jetty.server.handler.ContextHandler;
50  import org.eclipse.jetty.servlet.api.ServletRegistration;
51  import org.eclipse.jetty.util.Loader;
52  import org.eclipse.jetty.util.log.Log;
53  import org.eclipse.jetty.util.log.Logger;
54  
55  
56  
57  
58  /* --------------------------------------------------------------------- */
59  /** Servlet Instance and Context Holder.
60   * Holds the name, params and some state of a javax.servlet.Servlet
61   * instance. It implements the ServletConfig interface.
62   * This class will organise the loading of the servlet when needed or
63   * requested.
64   *
65   * 
66   */
67  public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope, Comparable
68  {
69      private static final Logger LOG = Log.getLogger(ServletHolder.class);
70  
71      /* ---------------------------------------------------------------- */
72      private int _initOrder;
73      private boolean _initOnStartup=false;
74      private Map<String, String> _roleMap;
75      private String _forcedPath;
76      private String _runAsRole;
77      private RunAsToken _runAsToken;
78      private IdentityService _identityService;
79      private ServletRegistration.Dynamic _registration;
80      
81      
82      private transient Servlet _servlet;
83      private transient Config _config;
84      private transient long _unavailable;
85      private transient UnavailableException _unavailableEx;
86      public static final Map<String,String> NO_MAPPED_ROLES = Collections.emptyMap();
87  
88      /* ---------------------------------------------------------------- */
89      /** Constructor .
90       */
91      public ServletHolder()
92      {
93      }
94  
95      
96      /* ---------------------------------------------------------------- */
97      /** Constructor for existing servlet.
98       */
99      public ServletHolder(String name,Servlet servlet)
100     {
101         setName(name);
102         setServlet(servlet);
103     }
104 
105     
106     /* ---------------------------------------------------------------- */
107     /** Constructor for existing servlet.
108      */
109     public ServletHolder(Servlet servlet)
110     {
111         setServlet(servlet);
112     }
113 
114     /* ---------------------------------------------------------------- */
115     /** Constructor for servlet class.
116      */
117     public ServletHolder(String name,Class<? extends Servlet> servlet)
118     {
119         setName(name);
120         setHeldClass(servlet);
121     }
122     
123     /* ---------------------------------------------------------------- */
124     /** Constructor for servlet class.
125      */
126     public ServletHolder(Class<? extends Servlet> servlet)
127     {
128         setHeldClass(servlet);
129     }
130 
131     /* ---------------------------------------------------------------- */
132     /**
133      * @return The unavailable exception or null if not unavailable
134      */
135     public UnavailableException getUnavailableException()
136     {
137         return _unavailableEx;
138     }
139     
140     /* ------------------------------------------------------------ */
141     public synchronized void setServlet(Servlet servlet)
142     {
143         if (servlet==null || servlet instanceof SingleThreadModel)
144             throw new IllegalArgumentException();
145 
146         _extInstance=true;
147         _servlet=servlet;
148         setHeldClass(servlet.getClass());
149         if (getName()==null)
150             setName(servlet.getClass().getName()+"-"+super.hashCode());
151     }
152     
153     /* ------------------------------------------------------------ */
154     public int getInitOrder()
155     {
156         return _initOrder;
157     }
158 
159     /* ------------------------------------------------------------ */
160     /** Set the initialize order.
161      * Holders with order<0, are initialized on use. Those with
162      * order>=0 are initialized in increasing order when the handler
163      * is started.
164      */
165     public void setInitOrder(int order)
166     {
167         _initOnStartup=true;
168         _initOrder = order;
169     }
170     
171     public boolean isSetInitOrder()
172     {
173         return _initOnStartup;
174     }
175 
176     /* ------------------------------------------------------------ */
177     /** Comparitor by init order.
178      */
179     public int compareTo(Object o)
180     {
181         if (o instanceof ServletHolder)
182         {
183             ServletHolder sh= (ServletHolder)o;
184             if (sh==this)
185                 return 0;
186             if (sh._initOrder<_initOrder)
187                 return 1;
188             if (sh._initOrder>_initOrder)
189                 return -1;
190             
191             int c=(_className!=null && sh._className!=null)?_className.compareTo(sh._className):0;
192             if (c==0)
193                 c=_name.compareTo(sh._name);
194             if (c==0)
195                 c=this.hashCode()>o.hashCode()?1:-1;
196             return c;
197         }
198         return 1;
199     }
200 
201     /* ------------------------------------------------------------ */
202     public boolean equals(Object o)
203     {
204         return compareTo(o)==0;
205     }
206 
207     /* ------------------------------------------------------------ */
208     public int hashCode()
209     {
210         return _name==null?System.identityHashCode(this):_name.hashCode();
211     }
212 
213     /* ------------------------------------------------------------ */
214     /** Link a user role.
215      * Translate the role name used by a servlet, to the link name
216      * used by the container.
217      * @param name The role name as used by the servlet
218      * @param link The role name as used by the container.
219      */
220     public synchronized void setUserRoleLink(String name,String link)
221     {
222         if (_roleMap==null)
223             _roleMap=new HashMap<String, String>();
224         _roleMap.put(name,link);
225     }
226     
227     /* ------------------------------------------------------------ */
228     /** get a user role link.
229      * @param name The name of the role
230      * @return The name as translated by the link. If no link exists,
231      * the name is returned.
232      */
233     public String getUserRoleLink(String name)
234     {
235         if (_roleMap==null)
236             return name;
237         String link= _roleMap.get(name);
238         return (link==null)?name:link;
239     }
240 
241     /* ------------------------------------------------------------ */
242     public Map<String, String> getRoleMap()
243     {
244         return _roleMap == null? NO_MAPPED_ROLES : _roleMap;
245     }
246     
247     /* ------------------------------------------------------------ */
248     /**
249      * @return Returns the forcedPath.
250      */
251     public String getForcedPath()
252     {
253         return _forcedPath;
254     }
255     
256     /* ------------------------------------------------------------ */
257     /**
258      * @param forcedPath The forcedPath to set.
259      */
260     public void setForcedPath(String forcedPath)
261     {
262         _forcedPath = forcedPath;
263     }
264     
265     /* ------------------------------------------------------------ */
266     public void doStart()
267         throws Exception
268     {
269         _unavailable=0;
270         try
271         {
272             super.doStart();
273             checkServletType();
274         }
275         catch (UnavailableException ue)
276         {
277             makeUnavailable(ue);
278         }
279 
280         _identityService = _servletHandler.getIdentityService();
281         if (_identityService!=null && _runAsRole!=null)
282             _runAsToken=_identityService.newRunAsToken(_runAsRole);
283         
284         _config=new Config();
285 
286         if (_class!=null && javax.servlet.SingleThreadModel.class.isAssignableFrom(_class))
287             _servlet = new SingleThreadedWrapper();
288 
289         if (_extInstance || _initOnStartup)
290         {
291             try
292             {
293                 initServlet();
294             }
295             catch(Exception e)
296             {
297                 if (_servletHandler.isStartWithUnavailable())
298                     LOG.ignore(e);
299                 else
300                     throw e;
301             }
302         }  
303     }
304 
305     /* ------------------------------------------------------------ */
306     public void doStop()
307         throws Exception
308     {
309         Object old_run_as = null;
310         if (_servlet!=null)
311         {       
312             try
313             {
314                 if (_identityService!=null)
315                     old_run_as=_identityService.setRunAs(_identityService.getSystemUserIdentity(),_runAsToken);
316 
317                 destroyInstance(_servlet);
318             }
319             catch (Exception e)
320             {
321                 LOG.warn(e);
322             }
323             finally
324             {
325                 if (_identityService!=null)
326                     _identityService.unsetRunAs(old_run_as);
327             }
328         }
329 
330         if (!_extInstance)
331             _servlet=null;
332 
333         _config=null;
334     }
335 
336     /* ------------------------------------------------------------ */
337     public void destroyInstance (Object o)
338     throws Exception
339     {
340         if (o==null)
341             return;
342         Servlet servlet =  ((Servlet)o);
343         getServletHandler().destroyServlet(servlet);
344         servlet.destroy();
345     }
346 
347     /* ------------------------------------------------------------ */
348     /** Get the servlet.
349      * @return The servlet
350      */
351     public synchronized Servlet getServlet()
352         throws ServletException
353     {
354         // Handle previous unavailability
355         if (_unavailable!=0)
356         {
357             if (_unavailable<0 || _unavailable>0 && System.currentTimeMillis()<_unavailable)
358                 throw _unavailableEx;
359             _unavailable=0;
360             _unavailableEx=null;
361         }
362 
363         if (_servlet==null)
364             initServlet();
365         return _servlet;
366     }
367 
368     /* ------------------------------------------------------------ */
369     /** Get the servlet instance (no initialization done).
370      * @return The servlet or null
371      */
372     public Servlet getServletInstance()
373     {
374         return _servlet;
375     }
376         
377     /* ------------------------------------------------------------ */
378     /**
379      * Check to ensure class of servlet is acceptable.
380      * @throws UnavailableException
381      */
382     public void checkServletType ()
383         throws UnavailableException
384     {
385         if (_class==null || !javax.servlet.Servlet.class.isAssignableFrom(_class))
386         {
387             throw new UnavailableException("Servlet "+_class+" is not a javax.servlet.Servlet");
388         }
389     }
390 
391     /* ------------------------------------------------------------ */
392     /** 
393      * @return true if the holder is started and is not unavailable
394      */
395     public boolean isAvailable()
396     {
397         if (isStarted()&& _unavailable==0)
398             return true;
399         try 
400         {
401             getServlet();
402         }
403         catch(Exception e)
404         {
405             LOG.ignore(e);
406         }
407 
408         return isStarted()&& _unavailable==0;
409     }
410     
411     /* ------------------------------------------------------------ */
412     private void makeUnavailable(UnavailableException e)
413     {
414         if (_unavailableEx==e && _unavailable!=0)
415             return;
416 
417         _servletHandler.getServletContext().log("unavailable",e);
418 
419         _unavailableEx=e;
420         _unavailable=-1;
421         if (e.isPermanent())   
422             _unavailable=-1;
423         else
424         {
425             if (_unavailableEx.getUnavailableSeconds()>0)
426                 _unavailable=System.currentTimeMillis()+1000*_unavailableEx.getUnavailableSeconds();
427             else
428                 _unavailable=System.currentTimeMillis()+5000; // TODO configure
429         }
430     }
431 
432     /* ------------------------------------------------------------ */
433 
434     private void makeUnavailable(final Throwable e)
435     {
436         if (e instanceof UnavailableException)
437             makeUnavailable((UnavailableException)e);
438         else
439         {
440             ServletContext ctx = _servletHandler.getServletContext();
441             if (ctx==null)
442                 LOG.info("unavailable",e);
443             else
444                 ctx.log("unavailable",e);
445             _unavailableEx=new UnavailableException(String.valueOf(e),-1)
446             {
447                 {
448                     initCause(e);
449                 }
450             };
451             _unavailable=-1;
452         }
453     }
454 
455     /* ------------------------------------------------------------ */
456     private void initServlet()
457     	throws ServletException
458     {
459         Object old_run_as = null;
460         try
461         {
462             if (_servlet==null)
463                 _servlet=newInstance();
464             if (_config==null)
465                 _config=new Config();
466             
467             // Handle run as
468             if (_identityService!=null)
469             {
470                 old_run_as=_identityService.setRunAs(_identityService.getSystemUserIdentity(),_runAsToken);
471             }
472             
473             // Handle configuring servlets that implement org.apache.jasper.servlet.JspServlet
474             if (isJspServlet())
475                 initJspServlet();
476 
477             _servlet.init(_config);
478             
479             if (isJspServlet())
480                postInitJspServlet();
481         }
482         catch (UnavailableException e)
483         {
484             makeUnavailable(e);
485             _servlet=null;
486             _config=null;
487             throw e;
488         }
489         catch (ServletException e)
490         {
491             makeUnavailable(e.getCause()==null?e:e.getCause());
492             _servlet=null;
493             _config=null;
494             throw e;
495         }
496         catch (Exception e)
497         {
498             makeUnavailable(e);
499             _servlet=null;
500             _config=null;
501             throw new ServletException(this.toString(),e);
502         }
503         finally
504         {
505             // pop run-as role
506             if (_identityService!=null)
507                 _identityService.unsetRunAs(old_run_as);
508         }
509     }
510     
511     
512     /* ------------------------------------------------------------ */
513     /**
514      * @throws Exception
515      */
516     protected void initJspServlet () throws Exception
517     {
518         ContextHandler ch = ((ContextHandler.Context)getServletHandler().getServletContext()).getContextHandler();
519         
520         /* Set the webapp's classpath for Jasper */
521         ch.setAttribute("org.apache.catalina.jsp_classpath", ch.getClassPath());
522 
523         /* Set the system classpath for Jasper */
524         setInitParameter("com.sun.appserv.jsp.classpath", Loader.getClassPath(ch.getClassLoader().getParent())); 
525         
526         /* Set up other classpath attribute */
527         if ("?".equals(getInitParameter("classpath")))
528         {
529             String classpath = ch.getClassPath();
530             LOG.debug("classpath=" + classpath);
531             if (classpath != null) 
532                 setInitParameter("classpath", classpath);
533         }
534     }
535     
536     protected void postInitJspServlet() throws Exception
537     {
538         try
539         {
540             //Check that jasper's SystemLogHandler class is on the classpath
541             Class systemLogHandlerClass = Loader.loadClass(this.getClass(), "org.apache.jasper.util.SystemLogHandler");
542             PrintStream rootSystemLogHandler = null;
543             while (systemLogHandlerClass.isAssignableFrom(System.err.getClass()))
544             {
545                 rootSystemLogHandler = System.err;
546                 Method getWrapped = systemLogHandlerClass.getMethod("getWrapped", new Class[]{});
547                 PrintStream ps = (PrintStream)getWrapped.invoke(System.err, new Object[]{});
548                 System.setErr(ps);
549             }
550             
551             if (rootSystemLogHandler != null)
552                 System.setErr(rootSystemLogHandler);
553         }
554         catch (ClassNotFoundException e)
555         {
556             //jasper not on classpath, ignore
557         }
558         catch (NoSuchMethodException e)
559         {
560             LOG.info("Problem unwrapping SystemLogHandler from System.err", e);
561         }
562         catch (SecurityException e)
563         {
564             LOG.warn("Problem unwrapping SystemLogHandler from System.err", e);
565         }
566         catch (IllegalAccessException e)
567         {
568             LOG.warn("Problem unwrapping SystemLogHandler from System.err", e);
569         }
570         catch (IllegalArgumentException e)
571         {
572             LOG.warn("Problem unwrapping SystemLogHandler from System.err", e);
573         }
574         catch (InvocationTargetException e)
575         {
576             LOG.warn("Problem unwrapping SystemLogHandler from System.err", e);
577         }
578         
579     }
580     
581     
582     /* ------------------------------------------------------------ */
583     /**
584      * @see org.eclipse.jetty.server.UserIdentity.Scope#getContextPath()
585      */
586     public String getContextPath()
587     {
588         return _config.getServletContext().getContextPath();
589     }
590 
591     /* ------------------------------------------------------------ */
592     /**
593      * @see org.eclipse.jetty.server.UserIdentity.Scope#getRoleRefMap()
594      */
595     public Map<String, String> getRoleRefMap()
596     {
597         return _roleMap;
598     }
599 
600     /* ------------------------------------------------------------ */
601     public String getRunAsRole() 
602     {
603         return _runAsRole;
604     }
605     
606     /* ------------------------------------------------------------ */
607     public void setRunAsRole(String role) 
608     {
609         _runAsRole = role;
610     }
611     
612     /* ------------------------------------------------------------ */
613     /** Service a request with this servlet.
614      */
615     public void handle(Request baseRequest,
616                        ServletRequest request,
617                        ServletResponse response)
618         throws ServletException,
619                UnavailableException,
620                IOException
621     {
622         if (_class==null)
623             throw new UnavailableException("Servlet Not Initialized");
624         
625         Servlet servlet=_servlet;
626         synchronized(this)
627         {
628             if (!isStarted())
629                 throw new UnavailableException("Servlet not initialized", -1);
630             if (_unavailable!=0 || !_initOnStartup)
631                 servlet=getServlet();
632             if (servlet==null)
633                 throw new UnavailableException("Could not instantiate "+_class);
634         }
635         
636         // Service the request
637         boolean servlet_error=true;
638         Object old_run_as = null;
639         boolean suspendable = baseRequest.isAsyncSupported();
640         try
641         {
642             // Handle aliased path
643             if (_forcedPath!=null)
644                 // TODO complain about poor naming to the Jasper folks
645                 request.setAttribute("org.apache.catalina.jsp_file",_forcedPath);
646 
647             // Handle run as
648             if (_identityService!=null)
649                 old_run_as=_identityService.setRunAs(baseRequest.getResolvedUserIdentity(),_runAsToken);
650             
651             if (!isAsyncSupported())
652                 baseRequest.setAsyncSupported(false);
653             
654             servlet.service(request,response);
655             servlet_error=false;
656         }
657         catch(UnavailableException e)
658         {
659             makeUnavailable(e);
660             throw _unavailableEx;
661         }
662         finally
663         {
664             baseRequest.setAsyncSupported(suspendable);
665             
666             // pop run-as role
667             if (_identityService!=null)
668                 _identityService.unsetRunAs(old_run_as);
669 
670             // Handle error params.
671             if (servlet_error)
672                 request.setAttribute("javax.servlet.error.servlet_name",getName());
673         }
674     }
675     
676     
677     /* ------------------------------------------------------------ */
678     private boolean isJspServlet ()
679     {
680         if (_servlet == null)
681             return false;
682         
683         Class c = _servlet.getClass();
684         
685         boolean result = false;
686         while (c != null && !result)
687         {
688             result = isJspServlet(c.getName());
689             c = c.getSuperclass();
690         }
691         
692         return result;
693     }
694     
695     
696     /* ------------------------------------------------------------ */
697     private boolean isJspServlet (String classname)
698     {
699         if (classname == null)
700             return false;
701         return ("org.apache.jasper.servlet.JspServlet".equals(classname));
702     }
703 
704  
705     /* ------------------------------------------------------------ */
706     /* ------------------------------------------------------------ */
707     /* ------------------------------------------------------------ */
708     protected class Config extends HolderConfig implements ServletConfig
709     {   
710         /* -------------------------------------------------------- */
711         public String getServletName()
712         {
713             return getName();
714         }
715         
716     }
717 
718     /* -------------------------------------------------------- */
719     /* -------------------------------------------------------- */
720     /* -------------------------------------------------------- */
721     public class Registration extends HolderRegistration implements ServletRegistration.Dynamic
722     {         
723         public Set<String> addMapping(String... urlPatterns)
724         {
725             illegalStateIfContextStarted();
726             Set<String> clash=null;
727             for (String pattern : urlPatterns)
728             {
729                 if (_servletHandler.getServletMapping(pattern)!=null)
730                 {
731                     if (clash==null)
732                         clash=new HashSet<String>();
733                     clash.add(pattern);
734                 }
735             }
736             
737             if (clash!=null)
738                 return clash;
739             
740             ServletMapping mapping = new ServletMapping();
741             mapping.setServletName(ServletHolder.this.getName());
742             mapping.setPathSpecs(urlPatterns);
743             _servletHandler.addServletMapping(mapping);
744             
745             return Collections.emptySet();
746         }
747 
748         public Collection<String> getMappings()
749         {
750             ServletMapping[] mappings =_servletHandler.getServletMappings();
751             List<String> patterns=new ArrayList<String>();
752             for (ServletMapping mapping : mappings)
753             {
754                 if (!mapping.getServletName().equals(getName()))
755                     continue;
756                 String[] specs=mapping.getPathSpecs();
757                 if (specs!=null && specs.length>0)
758                     patterns.addAll(Arrays.asList(specs));
759             }
760             return patterns;
761         }
762 
763         public String getRunAsRole() 
764         {
765             return _runAsRole;
766         }
767 
768         public void setLoadOnStartup(int loadOnStartup)
769         {
770             illegalStateIfContextStarted();
771             ServletHolder.this.setInitOrder(loadOnStartup);
772         }
773         
774         public int getInitOrder()
775         {
776             return ServletHolder.this.getInitOrder();
777         }
778  
779         public void setRunAsRole(String role) 
780         {
781             _runAsRole = role;
782         }
783     }
784     
785     public ServletRegistration.Dynamic getRegistration()
786     {
787         if (_registration == null)
788             _registration =  new Registration();
789         return _registration;
790     }
791     
792     /* -------------------------------------------------------- */
793     /* -------------------------------------------------------- */
794     /* -------------------------------------------------------- */
795     private class SingleThreadedWrapper implements Servlet
796     {
797         Stack<Servlet> _stack=new Stack<Servlet>();
798         
799         public void destroy()
800         {
801             synchronized(this)
802             {
803                 while(_stack.size()>0)
804                     try { (_stack.pop()).destroy(); } catch (Exception e) { LOG.warn(e); }
805             }
806         }
807 
808         public ServletConfig getServletConfig()
809         {
810             return _config;
811         }
812 
813         public String getServletInfo()
814         {
815             return null;
816         }
817 
818         public void init(ServletConfig config) throws ServletException
819         {
820             synchronized(this)
821             {
822                 if(_stack.size()==0)
823                 {
824                     try
825                     {
826                         Servlet s = newInstance();
827                         s.init(config);
828                         _stack.push(s);
829                     }
830                     catch (ServletException e)
831                     {
832                         throw e;
833                     }
834                     catch (Exception e)
835                     {
836                         throw new ServletException(e);
837                     }
838                 }
839             }
840         }
841 
842         public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
843         {
844             Servlet s;
845             synchronized(this)
846             {
847                 if(_stack.size()>0)
848                     s=(Servlet)_stack.pop();
849                 else
850                 {
851                     try
852                     {
853                         s = newInstance();
854                         s.init(_config);
855                     }
856                     catch (ServletException e)
857                     {
858                         throw e;
859                     }
860                     catch (Exception e)
861                     {
862                         throw new ServletException(e);
863                     }
864                 }
865             }
866             
867             try
868             {
869                 s.service(req,res);
870             }
871             finally
872             {
873                 synchronized(this)
874                 {
875                     _stack.push(s);
876                 }
877             }
878         }
879     }
880     
881     /* ------------------------------------------------------------ */
882     /**
883      * @return the newly created Servlet instance
884      * @throws ServletException
885      * @throws IllegalAccessException
886      * @throws InstantiationException
887      */
888     protected Servlet newInstance() throws ServletException, IllegalAccessException, InstantiationException
889     {
890         try
891         {
892             ServletContext ctx = getServletHandler().getServletContext();
893             if (ctx==null)
894                 return getHeldClass().newInstance();
895             return ((ServletContextHandler.Context)ctx).createServlet(getHeldClass());
896         }
897         catch (ServletException se)
898         {
899             Throwable cause = se.getRootCause();
900             if (cause instanceof InstantiationException)
901                 throw (InstantiationException)cause;
902             if (cause instanceof IllegalAccessException)
903                 throw (IllegalAccessException)cause;
904             throw se;
905         }
906     }
907 }
908 
909 
910 
911 
912