protected void initChannel() {
    if (channel == null) {
      buildChannel();
      String transportNodeName = configuration.getTransportNodeName();
      if (transportNodeName != null && transportNodeName.length() > 0) {
        long range = Short.MAX_VALUE * 2;
        long randomInRange = (long) ((Math.random() * range) % range) + 1;
        transportNodeName = transportNodeName + "-" + randomInRange;
        channel.setName(transportNodeName);
      }
    }

    // Channel.LOCAL *must* be set to false so we don't see our own messages - otherwise
    // invalidations targeted at remote instances will be received by self.
    channel.setDiscardOwnMessages(true);

    // if we have a TopologyAwareConsistentHash, we need to set our own address generator in
    // JGroups
    if (configuration.hasTopologyInfo()) {
      // We can do this only if the channel hasn't been started already
      if (startChannel) {
        ((JChannel) channel)
            .setAddressGenerator(
                new AddressGenerator() {

                  @Override
                  public org.jgroups.Address generateAddress() {
                    return TopologyUUID.randomUUID(
                        channel.getName(),
                        configuration.getSiteId(),
                        configuration.getRackId(),
                        configuration.getMachineId());
                  }
                });
      } else {
        if (channel.getAddress() instanceof TopologyUUID) {
          TopologyUUID topologyAddress = (TopologyUUID) channel.getAddress();
          if (!configuration.getSiteId().equals(topologyAddress.getSiteId())
              || !configuration.getRackId().equals(topologyAddress.getRackId())
              || !configuration.getMachineId().equals(topologyAddress.getMachineId())) {
            throw new CacheException(
                "Topology information does not match the one set by the provided JGroups channel");
          }
        } else {
          throw new CacheException("JGroups address does not contain topology coordinates");
        }
      }
    }
  }
  @Override
  public Channel createChannel(String id) throws Exception {
    JChannel channel = new MuxChannel(this);

    // We need to synchronize on shared transport,
    // so we don't attempt to init a shared transport multiple times
    TP transport = channel.getProtocolStack().getTransport();
    if (transport.isSingleton()) {
      synchronized (transport) {
        this.init(transport);
      }
    } else {
      this.init(transport);
    }

    channel.setName(configuration.getEnvironment().getNodeName() + "/" + id);

    TransportConfiguration transportConfiguration = this.configuration.getTransport();
    if (transportConfiguration.hasTopology()) {
      channel.setAddressGenerator(
          new TopologyAddressGenerator(
              channel,
              transportConfiguration.getSiteId(),
              transportConfiguration.getRackId(),
              transportConfiguration.getMachineId()));
    }

    MBeanServer server = this.configuration.getMBeanServer();
    if (server != null) {
      try {
        this.channels.put(channel, id);
        JmxConfigurator.registerChannel(channel, server, id);
      } catch (Exception e) {
        ROOT_LOGGER.warn(e.getMessage(), e);
      }
      channel.addChannelListener(this);
    }

    return channel;
  }