facebook

AccessControlException in SOAP client applet

  1. MyEclipse IDE
  2.  > 
  3. Off Topic
Viewing 15 posts - 1 through 15 (of 17 total)
  • Author
    Posts
  • #269468 Reply

    Peter Darton
    Member

    Folks,

    I’m trying to write a Java GUI that’ll talk to the “other end” via SOAP.
    I’ve generated my Java SOAP code using the “top down” approach, pointing MyEclipse at my WSDL code and letting it generate me some Java code.
    I then wrote a static method which takes a URL and basic-authentication parameters and returns me a Java instance that gives me a connection to the remote target.
    This all works fine unless I run my code as a Java applet, at which point the (previously working) code fails with an AccessControlException.
    I could understand an applet not being permitted to talk to other servers, but I’m just trying to talk SOAP back to the server I was downloaded from. I’ve double-checked the URL I’m trying to talk to, and it’s the same server, and the exception says RuntimePermission accessDeclaredMembers rather than an inability to talk over the network.

    It seems to me that MyEclipse has generated code that’s not usable in an applet as it’s trying to do things that an applet isn’t permitted to do!
    How can I get MyEclipse to generate SOAP client code that can be used in an applet?

    Thanks,

    Peter


    The exception I get is as follows, where mycode.wsdl is the auto-generated code and mycode.client is the code snippet listed after:

    Exception in thread "Thread-6" java.security.AccessControlException: access denied (java.lang.RuntimePermission accessDeclaredMembers)
        at java.security.AccessControlContext.checkPermission(Unknown Source)
        at java.security.AccessController.checkPermission(Unknown Source)
        at java.lang.SecurityManager.checkPermission(Unknown Source)
        at java.lang.SecurityManager.checkMemberAccess(Unknown Source)
        at java.lang.Class.checkMemberAccess(Unknown Source)
        at java.lang.Class.getDeclaredMethods(Unknown Source)
        at sun.reflect.annotation.AnnotationType.<init>(Unknown Source)
        at sun.reflect.annotation.AnnotationType.getInstance(Unknown Source)
        at sun.reflect.annotation.AnnotationParser.parseAnnotation(Unknown Source)
        at sun.reflect.annotation.AnnotationParser.parseAnnotations2(Unknown Source)
        at sun.reflect.annotation.AnnotationParser.parseAnnotations(Unknown Source)
        at java.lang.Class.initAnnotationsIfNecessary(Unknown Source)
        at java.lang.Class.getAnnotation(Unknown Source)
        at java.lang.Class.isAnnotationPresent(Unknown Source)
        at org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations.hasWebServiceAnnotation(Jsr181WebAnnotations.java:37)
        at org.codehaus.xfire.annotations.AnnotationServiceFactory.create(AnnotationServiceFactory.java:168)
        at org.codehaus.xfire.service.binding.ObjectServiceFactory.create(ObjectServiceFactory.java:353)
        at mycode.wsdl.JcadClient.create0(JcadClient.java:87)
        at mycode.wsdl.JcadClient.<init>(JcadClient.java:31)
        at mycode.client.JcadClientFactory.getProxy(JcadClientFactory.java:30)
        at mycode....

    This is the entry point to the auto-generated code:

    public class JcadClientFactory
    {
      ... comments cut for brevity
      public static JcadPortType getProxy(final String url, final String username,
              final String password)
      {
        // next line is line 30, where the exception happens
        final JcadPortType jcadPortType = new JcadClient().getJcadHttpPort();
        final Client client = Client.getInstance(jcadPortType);
        if( url != null ) {
          client.setUrl(url);
        }
        if( username != null && password != null ) {
          client.setProperty(Channel.USERNAME, username);
          client.setProperty(Channel.PASSWORD, password);
        }
        return jcadPortType;
      }
    #269469 Reply

    Peter Darton
    Member

    Oh yes, I forgot to post my MyEclipse details…

    *** Date: 
    27 April 2007 12:52:21 o'clock BST
    
    ** System properties:
    OS=WindowsXP
    OS version=5.1
    Java version=1.5.0_04
    
    
    *** MyEclipse details:
    MyEclipse Enterprise Workbench
    Version: 5.1.1 GA
    Build id: 20070302-5.1.1-GA
    
    
    *** Eclipse details:
    MyEclipse Enterprise Workbench
    
    Version: 5.1.1 GA
    Build id: 20070302-5.1.1-GA
    
    
    
    
    Eclipse Platform
    
    Version: 3.2.2.r322_v20070119-RQghndJN8IM0MsK
    Build id: M20070212-1330
    
    
    Eclipse RCP
    
    Version: 3.2.2.r322_v20070104-8pcviKVqd8J7C1U
    Build id: M20060921-0945
    
    
    Eclipse Java Development Tools
    
    Version: 3.2.2.r322_v20070104-R4CR0Znkvtfjv9-
    Build id: M20060921-0945
    
    
    Eclipse Plug-in Development Environment
    
    Version: 3.2.1.r321_v20060823-6vYLLdQ3Nk8DrFG
    Build id: M20060921-0945
    
    
    Eclipse Project SDK
    
    Version: 3.2.2.r322_v20070104-dCGKm0Ln38lm-8s
    Build id: M20070212-1330
    
    
    Eclipse Graphical Editing Framework
    
    Version: 3.2.2.v20070208
    Build id: 20070208-1315
    
    
    
    
    Eclipse startup command=-os
    win32
    -ws
    win32
    -arch
    x86
    -launcher
    D:\Apps\Eclipse-3.2.1\eclipse.exe
    -name
    Eclipse
    -showsplash
    600
    -exitdata
    380_78
    -product
    com.genuitec.myeclipse.product.ide
    -vm
    C:\Program Files\Java\jdk1.5.0_04\bin\javaw.exe
    
    
    #269474 Reply

    tomeksz
    Member

    I don’t think your problem has anything to do with myeclipse or SOAP.
    Try to open connection ( with e.g. URL object ) to the service url ( or service wsdl ) and check if applet can connect to it.

    #269484 Reply

    Riyad Kalla
    Member

    Moving to OT > Soft Dev

    #269496 Reply

    Peter Darton
    Member

    tomeksz:
    Good idea (it wouldn’t be the first time I’ve been entirely wrong), but I can confirm that my applet can talk back to the server from whence it came. If I deliberately screw up the URL (by changing the either hostname or port number), I get a

    AccessControlException(java.net.SocketPermission)

    thrown and not the

    AccessControlException(java.lang.RuntimePermission accessDeclaredMembers)

    that one gets from the MyEclipse-generated code.
    i.e. If I try to break the rules of applets only ever talking back to the server they came from, I get one error but if I try to run the MyEclipse-generated code, I get a different exception.

    For example, if all I wrote was

    public void triggerFault() { new JcadClient(); }

    where JcadClient is the class generated using MyEclipse’s “top down” (WSDL to Java) code generation facility, the problem remains – calling triggerFault() will cause an exception if run in an applet 🙁
    Whilst it wouldn’t be the first time I’ve stared at code and completely missed the bug under my nose, I challenge anyone to find a bug in code that simple 😀

    The problem is that I don’t know of any other way of calling the MyEclipse-generated code – the entry point is a class with no static methods and a default constructor that causes this damned AccessControlException when called. I’ve looked through the “top down” code generation wizard in MyEclipse, and I can’t see any tick box marked “generate code that works in applets” that I missed first time around.
    Basically, there doesn’t seem to be anything I can do from my code to prevent it, other than not use MyEclipse

    support-rkalla:
    I belive, therefore, that it is a MyEclipse fault – the exception is coming from code that was generated using MyEclipse – the code MyEclipse created simply does not work in a web browser applet environment, throwing “java.security.AccessControlException: access denied (java.lang.RuntimePermission accessDeclaredMembers)” when it gets called (and called in the only way the api allows!).
    So either MyEclipse is at fault, or I’m missing something in the way I should be using it.

    However, when all’s said and done, I don’t really care where the damned fault lies, I just want the some Java I can run in an applet environment so I can call my web service!
    MyEclipse claimed to provide WSDL to Java facilities as part of its “Web Services” functionality, but these don’t seem to work terribly well, hence why I posted in the “Web Services” forum.
    It sure isn’t a generic software development issue – there really isn’t much about “{ new JcadClient(); }” one can discuss!

    #269501 Reply

    Riyad Kalla
    Member

    Peter, now you have enraged my brain and I’m not going to be able to sleep until we figure out why this is happening.

    What do the contents of your jcad constructor look like? Are any of the endpoints being registered NOT from the originating server?

    #269504 Reply

    tomeksz
    Member

    Ok, after all you can be right 🙂 I think it over and maybe problem is caused by System.getProperty(“http.proxyHost”) ( or http.proxyPort, http.proxy.user ). I’ve never write any applet so its only a guess, but can you try to run System.getProperty(“http.proxyHost”) in your applet and check what happened. Also if you can, you can debug a little XFire code and check if this really a problem ( i can assist you a little ), if this is really problem then let me know i ‘ll fix it before next release.

    BTW: Nice new forum design 😀

    #269512 Reply

    Peter Darton
    Member

    support-rkalla:
    Hmm, enraged brain – sounds painful!
    The auto-generated code (as much as gets executed before the exception) is as follows:

    public class JcadClient
    {
      private static XFireProxyFactory proxyFactory = new XFireProxyFactory();
      private HashMap                  endpoints    = new HashMap();
      private Service                  service0;
      public JcadClient()
      {
        create0(); // exception thrown in this method
    ...

    and the offending method “create0()” is as follows:

      private void create0()
      {
        TransportManager tm =
          (org.codehaus.xfire.XFireFactory.newInstance().getXFire()
                  .getTransportManager());
        HashMap props = new HashMap();
        props.put("annotations.allow.interface", true);
        AnnotationServiceFactory asf =
          new AnnotationServiceFactory(new Jsr181WebAnnotations(), tm,
                  new AegisBindingProvider(new JaxbTypeRegistry()));
        asf.setBindingCreationEnabled(false);
        service0 = asf.create((mycode.wsdl.JcadPortType.class),
                          props); // exception thrown here
        ...

    As for

    Are any of the endpoints being registered NOT from the originating server?

    the answer is “yes” – the WDSL has a fake URL in it:

    <wsdlsoap:address location="/Jcad/services/Jcad" />

    as the service gets deployed on lots of servers, and I don’t know their hostname at the time the client code gets auto-generated (not that this should matter as the client code should be able to talk to any server).
    Whilst this is a valid concern, I’m not convinced that the code is actually getting far enough to read in a non-permitted URL – JcadPortType doesn’t mention target URLs, and whilst JcadClient does set up a default URL, it doesn’t get that far before the exception happens (the default URL gets set in the lines after the “…” in “create0()”). From looking at the backtrace on the original exception, I believe the exception happens when the JSR181 code tries to look at the annotations, and hence shouldn’t be because of the content of those annotations.
    I can probably try hard-coding the location (URL) to see if that makes a difference, but that isn’t a usable final solution for me (although it might help find the bug) – I need to deploy my applet code on multiple servers, each of which will have its own hostname (which can be reconfigured post install time).

    tomeksz:

    System.getProperty(“http.proxyHost”)

    this causes a

    java.security.AccessControlException: access denied (java.util.PropertyPermission http.proxyHost read)

    I don’t think the code is actually getting as far as actually trying to connect to anything – it looks like the exception hits before the code knows enough to attempt a connection.
    As for debugging, I’m happy to help you help me 😉 However, I’m not sure how to debug an applet within a browser and the exception doesn’t seem to occur if one asks MyEclipse to run the applet as an applet – I’m not convinced that MyEclipse sandboxes the applet to the same extent that a browser would.

    #269513 Reply

    tomeksz
    Member

    Can you try changing your code to :
    new JcadClient().getJcadHttpPort(MY_SERVER_URL); ?

    #269522 Reply

    Peter Darton
    Member

    tomeksz:
    Ok, tried that – no difference. The code doesn’t get far enough for changes to the getJcadHttpPort call to be relevant.
    e.g. I changed my code to read

      public static JcadPortType getProxy(final String url, final String username,
              final String password)
      {
        final JcadClient jcadClient = new JcadClient(); // exception happens here!
        final JcadPortType jcadPortType = jcadClient.getJcadHttpPort(url);

    and the code blows up on the “jcadClient = new JcadClient()” line.
    i.e. we don’t get as far as calling any methods on the JcadClient instance as it’s the constructor that fails with the exception.

    #269523 Reply

    tomeksz
    Member

    I’m afraid i can’t do much w/o knowing which line cause exception. Maybe someone can help you with debuging this code ?

    #269527 Reply

    Peter Darton
    Member

    I’ve listed all the code I’ve got access to in my earlier post.
    When the auto-generated code calls AnnotationServiceFactory.create(…), it then goes into the MyEclipse-supplied JAR file “xfire-core-1.2.2.jar” which, like all the MyEclipse libraries, has no source, hence I can’t single-step the code with any more detail than that.
    (Side issue: Why don’t the MyEclipse libraries come with the source already set up? It’s the single most useful thing anyone can do when providing a library, as it then lets people debug things properly and ensures that the tooltips/help etc shows real argument names and proper javadocs for all the methods. Without that, there’s little point in using an IDE instead of Notepad or vi, and if you’re not going to provide the source with a library, you’re just forcing developers to create their own library entry that includes both the executable code and the source and thus not use your library definition!)

    So, given the lack of source, I can debug & single-step as much as MyEclipse lets me, but the exception is thrown deep in code that MyEclipse shows as “Source not found”.
    I can tell you that single stepping the code (starting from the line we know in JcadClient.create0) gives the following (not terribly helpful) execution trace:

    • AnnotationServiceFactory.create(Class,Map) line 353, calls
    • AnnotationServiceFactory.create(Class,String,String,Map) line 163
    • AnnotationServiceFactory.create(Class,String,String,Map) line 164
    • AnnotationServiceFactory.create(Class,String,String,Map) line 166
    • AnnotationServiceFactory.create(Class,String,String,Map) line 168, which calls
    • Jsr181WebAnnotations.hasWebServiceAnnotation(Class) line 37, which calls
    • Launcher$AppClassLoader(ClassLoader).loadClassInternal(String) line 319 (source available)
      Step-return takes us back to…
    • Jsr181WebAnnotations.hasWebServiceAnnotation(Class) line 37 (source unavailable), which calls
    • Class<T>.isAnnotationPresent(Class<Annotation>) line 2967 (source available)
    • Class<T>.isAnnotationPresent(Class<Annotation>) line 2970, which calls
    • Class<T>.getAnnotation(Class<A>) line 2955
    • Class<T>.getAnnotation(Class<A>) line 2958, which calls
    • Class<T>.initAnnotationsIfNecessary() line 2996
    • Class<T>.initAnnotationsIfNecessary() line 2998, which calls
    • ConstantPool.<clinit>() line 42
      Step return takes us back to…
    • Class<T>.initAnnotationsIfNecessary() line 2998, which calls
    • AnnotationParser.parseAnnotations(byte[], ConstantPool, Class) line 48 (no source)

    I think the exception gets thrown from somewhere under this last method call – i.e. that call to parseAnnotations does not return anything but instead throws the exception. I’ve not been able to check this 100% (if you ask MyEclipse to run or debug “as applet”, it does not run it with applet security permissions but instead permits the code to do anything), but parseAnnotations doesn’t get called from where else in initAnnocationsIfNecessary(), so it’s the only possible call it can be given the exception backtrace.

    #269539 Reply

    Riyad Kalla
    Member

    pjdarton,
    Could you grab the XFIre source from here: http://dist.codehaus.org/xfire/sources/xfire-src-1.2.2.zip

    attach it and try the trace again and see what’s happening? It will help us (both Tom and I) figure out what is going on and where.

    #269544 Reply

    Peter Darton
    Member

    Ok, I’ve told MyEclipse that the source to the various xfire jar files is in xfire-src-1.2.2.zip. That’s allowed MyEclipse to actually show me what source code it is really executing (Side issue: Why isn’t it like that by default?)
    That means that the trace now goes as follows:

    • we start in the auto-generated code
          ...
          service0 = asf.create((mycode.wsdl.JcadPortType.class),
                            props); // exception thrown here
          ...
    • which calls AnnotationServiceFactory.create(Class,Map) line 353
          public Service create(Class clazz, Map properties)
          {
              return create(clazz, (String) null, (String) null, properties);
          }
      
    • which calls AnnotationServiceFactory.create(Class,String,String,Map) line 163
          public Service create(final Class clazz, String name, String namespace, Map properties)
          {
              String style = null;
              String use = null;
              
              if (properties == null) properties = new HashMap();
      
              if (webAnnotations.hasWebServiceAnnotation(clazz))
              ...
    • which calls Jsr181WebAnnotations.hasWebServiceAnnotation(Class) line 37
          public boolean hasWebServiceAnnotation(Class clazz)
          {
              return clazz.isAnnotationPresent(WebService.class);
          }
      
    • which calls Class<T>.isAnnotationPresent(Class<Annotation>) line 2967
          public boolean isAnnotationPresent(
              Class<? extends Annotation> annotationClass) {
              if (annotationClass == null)
                  throw new NullPointerException();
      
              return getAnnotation(annotationClass) != null;
          }
    • which calls Class<T>.getAnnotation(Class<A>) line 2955
          public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
              if (annotationClass == null)
                  throw new NullPointerException();
      
              initAnnotationsIfNecessary();
              ...
    • which calls Class<T>.initAnnotationsIfNecessary() line 2996
          private synchronized void initAnnotationsIfNecessary() {
              if (annotations != null)
                  return;
              declaredAnnotations = AnnotationParser.parseAnnotations(
                  getRawAnnotations(), getConstantPool(), this);
              ...
    • which calls AnnotationParser.parseAnnotations(byte[], ConstantPool, Class) line 48 (no source)
    • which throws the exception (see message at start of thread for full text)

    The above trace is subject to the same disclaimers as the previous step-trace – as if I tell MyEclipse to run an applet class as an applet, it grants far more permissions than an applet normally has (i.e. not really like an applet at all!), hence doesn’t show this exception.
    If the above wasn’t what you were after, please clarify and I’ll try to provide the appropriate data.

    #269548 Reply

    Riyad Kalla
    Member

    source code it is really executing (Side issue: Why isn’t it like that by default?)

    Size. We’ve been wanting to do it since our 2.x days, but the size of the source practically doubles our library size. If you go count how many megs of MyEclipse are actually libraries, it’s sizable… then you double that, and people are pretty much downloading CD Images instead of multi-hundred meg installers 🙁

    First, awesome stack trace… thank you for going through all that.

    Second, this seems to be a JDK-level issue, see here: http://forums.java.net/jive/thread.jspa?messageID=211774

    guy having exactly the same problem with JAXB in an Applet. Not sure what the solution is, but this isn’t MyEclipse’s issue or XFire… this is lower level.

    I ran into a problem very similar to this with early releases of JAXB to… turns out when you try and parse something from a web start app it would fail with security exception because it tried to use the default ClassLoader and not the Web Start one… was a huge bummer running into a platform bug like that. Ended up ripping all the code out and using Castor instead.

Viewing 15 posts - 1 through 15 (of 17 total)
Reply To: AccessControlException in SOAP client applet

You must be logged in to post in the forum log in