Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4809366

all-permissions does not grant permission for getClassLoader()

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P3 P3
    • None
    • 1.2.0
    • deploy
    • x86
    • windows_xp



      Name: nt126004 Date: 01/28/2003


      FULL PRODUCT VERSION :
      Command-line version info:

      java version "1.3.1_04"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_04-b02)
      Java HotSpot(TM) Client VM (build 1.3.1_04-b02, mixed mode)

      Java WebStart version info:

      Java Web Start 1.2 Console, started Thu Dec 26 12:48:11 CST 2002

      Java 2 Runtime Environment: Version 1.3.1_04 by Sun Microsystems Inc.


      FULL OPERATING SYSTEM VERSION :

      Microsoft Windows XP [Version 5.1.2600]

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      Java Webstart 1.2 (also seen in 1.0.1)

      A DESCRIPTION OF THE PROBLEM :
      Our application gets a java.security.AccessControlException
      when running from Java WebStart. It successfully runs when
      started from the command line (with null SecurityManager).

      The jar files are signed and the jnlp file requests
      all-permissions. Java WebStart starts executing the
      application, but it quickly stops with the exception.

      This a command-line JMS client application using the BEA
      WebLogic 7.0SP1 jar files to talk to BEA's JMS
      implementation. This is just a simple utility that
      demonstrates a general problem using BEA's WLS 7.0SP1
      libraries with java webstart.

      We see this bug with Java WebStart 1.0.1_01 also.

      (Please see comments)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. build app
      2. jar it up
      3. sign app jar and weblogic WLS 7.0SP1 jar file
      4. install on web server with .jnlp file shown
      5. launch w/ web browser (using java webstart) and see exception

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      Application should successfully initialize.


      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      java.security.AccessControlException: access denied (java.lang.RuntimePermission
      getClassLoader)

      at java.security.AccessControlContext.checkPermission(Unknown Source)
      at java.security.AccessController.checkPermission(Unknown Source)
      at java.lang.SecurityManager.checkPermission(Unknown Source)
      at java.lang.ClassLoader.getParent(Unknown Source)
      at
      weblogic.rmi.internal.ClientRuntimeDescriptor.computeInterfaces(ClientRuntimeDescriptor.java:253)
      at
      weblogic.rmi.internal.ClientRuntimeDescriptor.intern(ClientRuntimeDescriptor.java:123)
      at weblogic.rmi.internal.StubInfo.readObject(StubInfo.java:100)
      at java.lang.reflect.Method.invoke(Native Method)
      at java.io.ObjectInputStream.invokeObjectReader(Unknown Source)
      at java.io.ObjectInputStream.inputObject(Unknown Source)
      at java.io.ObjectInputStream.readObject(Unknown Source)
      at java.io.ObjectInputStream.readObject(Unknown Source)
      at
      weblogic.common.internal.ChunkedObjectInputStream.readObject(ChunkedObjectInputStream.java:140)
      at
      weblogic.jms.client.JMSConnectionFactory.readExternal(JMSConnectionFactory.java:173)
      at
      weblogic.common.internal.ChunkedObjectInputStream.readObject(ChunkedObjectInputStream.java:131)
      at weblogic.rjvm.MsgAbbrevInputStream.readObject(MsgAbbrevInputStream.java:91)
      at weblogic.rmi.internal.ObjectIO.readObject(ObjectIO.java:56)
      at weblogic.rjvm.ResponseImpl.unmarshalReturn(ResponseImpl.java:161)
      at
      weblogic.rmi.cluster.ReplicaAwareRemoteRef.invoke(ReplicaAwareRemoteRef.java:263)
      at
      weblogic.rmi.cluster.ReplicaAwareRemoteRef.invoke(ReplicaAwareRemoteRef.java:229)
      at weblogic.jndi.internal.ServerNamingNode_WLStub.lookup(Unknown Source)
      at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:337)
      at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:332)
      at javax.naming.InitialContext.lookup(Unknown Source)
      at com.ti.mtc.facops.util.TopicDump.init(TopicDump.java:113)
      at com.ti.mtc.facops.util.TopicDump.<init>(TopicDump.java:107)
      at com.ti.mtc.facops.util.TopicDump.main(TopicDump.java:91)
      at java.lang.reflect.Method.invoke(Native Method)
      at com.sun.javaws.Launcher.executeApplication(Unknown Source)
      at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
      at com.sun.javaws.Launcher.continueLaunch(Unknown Source)
      at com.sun.javaws.Launcher.handleApplicationDesc(Unknown Source)
      at com.sun.javaws.Launcher.handleLaunchFile(Unknown Source)
      at com.sun.javaws.Launcher.run(Unknown Source)
      at java.lang.Thread.run(Unknown Source)


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      // see comments section

      /** This class will create connections to a JMS topic and dump the messages
      being distributed.

      */

      package com.ti.mtc.facops.util;

      import java.util.*;
      import javax.naming.*;
      import javax.jms.*;

      public class TopicDump
          implements MessageListener, ExceptionListener
      {
          private static final java.text.DateFormat DATE_FORMAT =
       new java.text.SimpleDateFormat("yyyy/MM/dd kk:mm:ss.SSS");
          static final String JMS_FACTORY="javax.jms.TopicConnectionFactory";

          private TopicConnectionFactory conFactory;
          private TopicConnection con;
          private TopicSession session;
          private TopicSubscriber consumer;
          private Topic destination;

          /** Run the program
           * @param args 0: JNDI name of destination
           */
          public static void main(String args[]) throws Exception {
       // Command-line processing. Ick, isn't there a class to do this?
       int argIndex; // This will point to first arg after optoins

       /** optional message selector */
       String selector = null;
       /** required JNDI name for Destination we'll read from */
       String jndiName = null;

       final String USAGE_STRING = "TopicDump [-selector selector] jndiName";

       try {
           for (argIndex = 0; argIndex < args.length; argIndex++) {
        String arg = args[argIndex];
        String argParm = (argIndex + 1 < args.length) ?
            args[argIndex + 1] : null;
          
        // We're outta here if not an option
        if (!arg.startsWith("-")) {
            break;
        }
         
        // Consume a -- end-of-args marker and exit
        if (arg.equals("--")) {
            argIndex++;
            break;
        }
          
        // Series of if/else if/else if... for the args we understand
        // Manually advance argIndex if an argParm is consumed
        if (arg.equals("-selector") && argParm != null) {
            // optional message selector
            selector = argParm;
            argIndex++;
        }
        // Other "else if" checks above here, end with this error "else"
        else {
            throw new Exception("Error parsing option \""
           + args[argIndex] + "\"");
        }
           }

           /* Set up for pre-increments next.
            * That's useful so argIndex points to bad arg if we get exception.
            */
           argIndex--;
           try {
        jndiName = args[++argIndex];
           } catch (Exception e) {
        throw new Exception("Exception " + e.getClass()
              + " parsing required parameter \""
              + ((argIndex < args.length) ? args[argIndex] : "(empty)")
              + "\"\n" + e);
           }
           // At the end, make sure there are no extra parameters
           if (argIndex + 1 < args.length) {
        throw new Exception("Ignoring extra parameters, \"" +
              args[argIndex + 1] + "\" and after");
           }
       } catch (Exception e) {
           throw new Exception(USAGE_STRING + "\n" + e.getMessage());
       }


       TopicDump d = new TopicDump(jndiName, selector);
       if (true) {
           d.dumpAsynchronously();
           // Wait forever
           synchronized (d) {
        d.wait();
           }
       }
       else {
           d.dumpMessages();
       }
       d.close();
          }

          public TopicDump(String jndiName, String selector) throws Exception {
       InitialContext ic = new InitialContext();
       init(ic, jndiName, selector);
          }

          /** Initialize JMS topic connection */
          private void init(Context ctx, String name, String selector)
       throws NamingException, JMSException {
       conFactory = (TopicConnectionFactory)ctx.lookup(JMS_FACTORY);
       con = conFactory.createTopicConnection();
       session = con.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
       destination = (Topic)ctx.lookup(name);

       con.setExceptionListener(this);

       // Create a consumer with the selector (if specified)
       // "noLocal" option isn't interesting as we don't publish, set false
       consumer = (selector == null) ?
           session.createSubscriber(destination) :
           session.createSubscriber(destination, selector, false);
       con.start();
          }

          /** Register us for async callback on message availability */
          void dumpAsynchronously() throws JMSException {
       consumer.setMessageListener(this);
          }

          /** Dump out messages. Exit when empty */
          void dumpMessages() throws Exception {
       while (true) {
           Message m;

           // If no messages available, break out
           m = consumer.receiveNoWait();
           if (m == null) {
        break;
           }

           // Process the message
           onMessage(m);
       }
          }

          /**
           * Closes JMS objects
           */
          public void close() {
       // silently ignore all exceptions
       try {consumer.close();} catch (Exception e) {};
       try {session.close();} catch (Exception e) {};
       try {con.close();} catch (Exception e) {};
          }


          /** Called automatically (or by us) on receipt of a message.
          */
          public void onMessage(javax.jms.Message msg) {
       try {
           String msgText;
           if (msg instanceof TextMessage) {
        msgText = ((TextMessage)msg).getText();
           } else if (msg instanceof ObjectMessage) {
        msgText = ((ObjectMessage)msg).getObject().toString();
           } else {
        msgText = msg.toString();
           }

           StringBuffer sb = new StringBuffer(8192);
           sb.append("Message: id=").append(msg.getJMSMessageID());
           sb.append(" corr=").append(msg.getJMSCorrelationID());
           sb.append(" dest=").append(msg.getJMSDestination());
           sb.append(" reply=").append(msg.getJMSReplyTo());
           sb.append(" ts=").append(DATE_FORMAT.format(new Date(msg.getJMSTimestamp())));
           System.out.println(sb.toString());

           sb = new StringBuffer(8192);
           sb.append("Properties:");
           for (Enumeration e = msg.getPropertyNames();
         e.hasMoreElements(); ) {
        String propName = (String)e.nextElement();
        sb.append(' ').append(propName).append('=');
        sb.append(msg.getObjectProperty(propName));
           }
           System.out.println(sb.toString());
           System.out.println(msgText);
           System.out.println("");
       } catch (Exception e) {
           e.printStackTrace(System.err);
       }
          }

          public void onException(JMSException e) {
       e.printStackTrace(System.err);
       close();

       // Wake us from the wait
       synchronized (this) {
           this.notifyAll();
       }
          }
      }


      Here's the .jnlp file

      <?xml version="1.0" encoding="UTF-8"?>

      <jnlp spec="1.0+"
      codebase="http://www.mtc.ti.com/applications/facops/whiteboard/javaws/test"
      href="TopicDump-neptune7001.jnlp">
             <information>
               <title>TopicDump</title>
               <vendor>Texas Instruments</vendor>
               <homepage href="http://www.mtc.ti.com/~jmaline/"/>
               <description>help me understand Java WebStart security</description>
               <description kind="short">security check</description>
               <offline-allowed/>
             </information>
             <resources>
               <j2se version="1.3"/>
               <jar href="facops.jar"/>
        <jar href="../wli70sp1/weblogic.jar"/>
               <property name="java.naming.factory.initial"
      value="weblogic.jndi.WLInitialContextFactory"/>
               <property name="java.naming.provider.url"
      value="t3://neptune.mtc.ti.com:7001"/>
             </resources>
              <security>
                      <all-permissions/>
              </security>
             <application-desc main-class="com.ti.mtc.facops.util.TopicDump">
        <argument>com.bea.wlpi.AuditTopic</argument>
             </application-desc>
           </jnlp>

      ---------- END SOURCE ----------

      CUSTOMER WORKAROUND :
      Edit jre\lib\security\java.policy files on client to grant
      the following:
       permission java.lang.RuntimePermission "getClassLoader";

      This is unsatisfying since it requires touching all the
      client computers. Plus I'm not sure if security
      implications of granting this.

      This is BEA's recommended workaround.
      (Review ID: 179436)
      ======================================================================

            herrick Andy Herrick (Inactive)
            nthompsosunw Nathanael Thompson (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: