Uploaded image for project: 'PUBLIC - Liferay Portal Community Edition'
  1. PUBLIC - Liferay Portal Community Edition
  2. LPS-79255

WebSocket Endpoint OSGi @Component with Multivalued property fails with java.lang.ClassCastException

    Details

    • Type: Bug
    • Status: Verified
    • Resolution: Unresolved
    • Affects Version/s: 7.0.X, 7.1.X, Master
    • Fix Version/s: None
    • Component/s: Core Infrastructure
    • Labels:
    • What problem did the customer find?:
      Multivalued OSGi @Component property item fails to get interpreted as java.util.List
    • What do you think is the root cause? (if known):
      Portal code in com.liferay.websocket.whiteboard.internal.WebSocketEndpointTracker#addingService(..) fails to convert multivalued property item into a String array, and then to a list (array interpretation is missing, conversion is faulty in operation).
    • Proposed solution (if any):
      Hide
      Implement the proper conversion routine for multivalued OSGi @Component property items:
      - from String to String array (even if it is a single item)
      - from String array to List<Class<?>>
      -- using Class.forName(..) to interpret array items
      Show
      Implement the proper conversion routine for multivalued OSGi @Component property items: - from String to String array (even if it is a single item) - from String array to List<Class<?>> -- using Class.forName(..) to interpret array items

      Description

      USE CASE
      We want to configure "org.osgi.http.websocket.endpoint.encoders" to be able to serialize objects to JSON and send them. The problem is that the method providing the value via @Component property does not work because Encoders has to be a list.

      ISSUE:
      OSGi @Component property item fails to get interpreted as java.util.List.

      REPRODUCTION STEPS:
      1. use official resources:
      https://dev.liferay.com/de/develop/tutorials/-/knowledge_base/7-0/liferay-websocket-whiteboard
      2. update the code to provide multi valued property items
      e.g.

      @Component(
          immediate = true,
          property = {
      		"org.osgi.http.websocket.endpoint.path=/o/echo",
      		"org.osgi.http.websocket.endpoint.encoders=com.liferay.websocket.example.json.JsonEncoder",
      		"org.osgi.http.websocket.endpoint.encoders=com.liferay.websocket.example.json.AnotherEncoder",
      		"org.osgi.http.websocket.endpoint.decoders=com.liferay.websocket.example.json.ADecoder"
      	},
          service = Endpoint.class
      )
      public class EchoWebSocketEndpoint extends Endpoint {
      
          @Override
          public void onOpen(final Session session, EndpointConfig endpointConfig) {
              session.addMessageHandler(
                  new MessageHandler.Whole<String>() {
                  @Override
                  public void onMessage(String text) {
                      try {
                          RemoteEndpoint.Basic remoteEndpoint =
                              session.getBasicRemote();
                          remoteEndpoint.sendText(text);
                      }
                      catch (IOException ioe) {
                          throw new RuntimeException(ioe);
                      }
                  }
              });
          }
      }
      

      (Note: the encoder class names are just for demonstrating the bug, do not refer to actual classes)
      3. build the bundle
      4. Start the portal.
      5. Deploy the bundle
      6 see the error message:

      15:57:17,317 ERROR [Framework Event Dispatcher: Equinox Container: 50ad1c64-2e1e-0018-1ca5-ebd598ec68b2][com_liferay_websocket_whiteboard:97] FrameworkEvent ERROR 
      java.lang.ClassCastException: java.lang.String cannot be cast to java.util.List
      	at com.liferay.websocket.whiteboard.internal.WebSocketEndpointTracker.addingService(WebSocketEndpointTracker.java:66)
      	at com.liferay.websocket.whiteboard.internal.WebSocketEndpointTracker.addingService(WebSocketEndpointTracker.java:47)
      	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:941)
      

      HYPOTHESIS:
      Portal code in com.liferay.websocket.whiteboard.internal.WebSocketEndpointTracker#addingService(..) fails to convert multi valued property item into a String[] array, and then to a List<Class>

      • array interpretation is missing
      • conversion is faulty in operation

      PROPOSED SOLUTION:
      Implement the proper conversion routine for multi valued OSGi @Component property items:

      • from String to String[] array (even if it is a single item)
      • from String[] array to List<Class>
        • using Class.forName(..) to interpret String[] array items

       

        Attachments

          Activity

            People

            • Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

              • Due:
                Created:
                Updated:
                Days since last comment:
                1 year, 4 weeks, 2 days ago

                Packages

                Version Package