Exemple #1
0
  public static void testWriteView() throws Exception {
    List<Address> members = new ArrayList<>();
    View v;
    Address a1 = Util.createRandomAddress();
    Address a2 = Util.createRandomAddress();
    Address a4 = Util.createRandomAddress();
    ViewId vid = new ViewId(a1, 12345);
    members.add(a1);
    members.add(a2);
    members.add(a4);
    v = new View(vid, members);

    ByteArrayOutputStream outstream = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(outstream);
    Util.writeGenericStreamable(v, dos);
    Util.writeStreamable(v, dos);
    dos.close();
    byte[] buf = outstream.toByteArray();
    ByteArrayInputStream instream = new ByteArrayInputStream(buf);
    DataInputStream dis = new DataInputStream(instream);
    View v2 = (View) Util.readGenericStreamable(dis);
    Assert.assertEquals(v, v2);
    v2 = (View) Util.readStreamable(View.class, dis);
    Assert.assertEquals(v, v2);
  }
Exemple #2
0
 public List<Integer> providedUpServices() {
   List<Integer> ret = new ArrayList<Integer>(3);
   ret.add(Event.FIND_INITIAL_MBRS);
   ret.add(Event.FIND_ALL_VIEWS);
   ret.add(Event.GET_PHYSICAL_ADDRESS);
   return ret;
 }
Exemple #3
0
  public static void testNewMembers() {
    final Address a = Util.createRandomAddress(),
        b = Util.createRandomAddress(),
        c = Util.createRandomAddress(),
        d = Util.createRandomAddress(),
        e = Util.createRandomAddress();
    List<Address> old = new ArrayList<>();
    List<Address> new_list = new ArrayList<>();

    old.add(a);
    old.add(b);
    old.add(c);
    new_list.add(b);
    new_list.add(a);
    new_list.add(c);
    new_list.add(d);
    new_list.add(e);

    System.out.println("old: " + old);
    System.out.println("new: " + new_list);

    List<Address> new_nodes = Util.newMembers(old, new_list);
    System.out.println("new_nodes = " + new_nodes);
    assert new_nodes.size() == 2 : "list should have d and e";
    assert new_nodes.contains(d);
    assert new_nodes.contains(e);
  }
Exemple #4
0
 public static void testAll() {
   List<String> l = new ArrayList<>();
   l.add("one");
   l.add("two");
   l.add("one");
   System.out.println("-- list is " + l);
   assert !(Util.all(l, "one"));
   l.remove("two");
   System.out.println("-- list is " + l);
   assert Util.all(l, "one");
 }
Exemple #5
0
  public void up(MessageBatch batch) {
    if (batch.dest() == null) { // not a unicast batch
      up_prot.up(batch);
      return;
    }

    int size = batch.size();
    Map<Short, List<Message>> msgs =
        new TreeMap<Short, List<Message>>(); // map of messages, keyed by conn-id
    for (Message msg : batch) {
      if (msg == null || msg.isFlagSet(Message.Flag.NO_RELIABILITY)) continue;
      UnicastHeader hdr = (UnicastHeader) msg.getHeader(id);
      if (hdr == null) continue;
      batch.remove(msg); // remove the message from the batch, so it won't be passed up the stack

      if (hdr.type != UnicastHeader.DATA) {
        try {
          handleUpEvent(msg.getSrc(), hdr);
        } catch (Throwable t) { // we cannot let an exception terminate the processing of this batch
          log.error(local_addr + ": failed handling event", t);
        }
        continue;
      }

      List<Message> list = msgs.get(hdr.conn_id);
      if (list == null) msgs.put(hdr.conn_id, list = new ArrayList<Message>(size));
      list.add(msg);
    }

    if (!msgs.isEmpty()) handleBatchReceived(batch.sender(), msgs); // process msgs:
    if (!batch.isEmpty()) up_prot.up(batch);
  }
Exemple #6
0
  protected List<PingData> read(InputStream in) {
    List<PingData> retval = null;
    try {
      while (true) {
        try {
          String name_str = Util.readToken(in);
          String uuid_str = Util.readToken(in);
          String addr_str = Util.readToken(in);
          String coord_str = Util.readToken(in);
          if (name_str == null || uuid_str == null || addr_str == null || coord_str == null) break;

          UUID uuid = null;
          try {
            long tmp = Long.valueOf(uuid_str);
            uuid = new UUID(0, tmp);
          } catch (Throwable t) {
            uuid = UUID.fromString(uuid_str);
          }

          PhysicalAddress phys_addr = new IpAddress(addr_str);
          boolean is_coordinator = coord_str.trim().equals("T") || coord_str.trim().equals("t");

          if (retval == null) retval = new ArrayList<>();
          retval.add(new PingData(uuid, true, name_str, phys_addr).coord(is_coordinator));
        } catch (Throwable t) {
          log.error(Util.getMessage("FailedReadingLineOfInputStream"), t);
        }
      }
      return retval;
    } finally {
      Util.close(in);
    }
  }
Exemple #7
0
  /**
   * Computes the next view. Returns a copy that has <code>old_mbrs</code> and <code>suspected_mbrs
   * </code> removed and <code>new_mbrs</code> added.
   */
  public View getNextView(
      Collection<Address> new_mbrs,
      Collection<Address> old_mbrs,
      Collection<Address> suspected_mbrs) {
    synchronized (members) {
      ViewId view_id = view != null ? view.getViewId() : null;
      if (view_id == null) {
        log.error("view_id is null");
        return null; // this should *never* happen !
      }
      long vid = Math.max(view_id.getId(), ltime) + 1;
      ltime = vid;
      Membership tmp_mbrs = tmp_members.copy(); // always operate on the temporary membership
      tmp_mbrs.remove(suspected_mbrs);
      tmp_mbrs.remove(old_mbrs);
      tmp_mbrs.add(new_mbrs);
      List<Address> mbrs = tmp_mbrs.getMembers();
      Address new_coord = local_addr;
      if (!mbrs.isEmpty()) new_coord = mbrs.get(0);
      View v = new View(new_coord, vid, mbrs);

      // Update membership (see DESIGN for explanation):
      tmp_members.set(mbrs);

      // Update joining list (see DESIGN for explanation)
      if (new_mbrs != null) {
        for (Address tmp_mbr : new_mbrs) {
          if (!joining.contains(tmp_mbr)) joining.add(tmp_mbr);
        }
      }

      // Update leaving list (see DESIGN for explanations)
      if (old_mbrs != null) {
        for (Address addr : old_mbrs) {
          if (!leaving.contains(addr)) leaving.add(addr);
        }
      }
      if (suspected_mbrs != null) {
        for (Address addr : suspected_mbrs) {
          if (!leaving.contains(addr)) leaving.add(addr);
        }
      }
      return v;
    }
  }
 /**
  * Add a new channel listener to be notified on the channel's state change.
  *
  * @return true if the listener was added or false if the listener was already in the list.
  */
 public boolean addChannelListener(ChannelListener l) {
   synchronized (additionalChannelListeners) {
     if (additionalChannelListeners.contains(l)) {
       return false;
     }
     additionalChannelListeners.add(l);
     return true;
   }
 }
Exemple #9
0
  public static void testPickRandomElement() {
    List<Integer> v = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
      v.add(i);
    }

    Integer el;
    for (int i = 0; i < 10000; i++) {
      el = Util.pickRandomElement(v);
      assert el >= 0 && el < 10;
    }
  }
Exemple #10
0
  protected void _handleMergeRequest(
      Address sender, MergeId merge_id, Collection<? extends Address> mbrs) throws Exception {
    boolean success = matchMergeId(merge_id) || setMergeId(null, merge_id);
    if (!success)
      throw new Exception(
          "merge " + this.merge_id + " is already in progress, received merge-id=" + merge_id);

    /* Clears the view handler queue and discards all JOIN/LEAVE/MERGE requests until after the MERGE  */
    // gms.getViewHandler().suspend();
    if (log.isTraceEnabled())
      log.trace(
          gms.local_addr
              + ": got merge request from "
              + sender
              + ", merge_id="
              + merge_id
              + ", mbrs="
              + mbrs);

    // merge the membership of the current view with mbrs
    List<Address> members = new LinkedList<Address>();
    if (mbrs
        != null) { // didn't use a set because we didn't want to change the membership order at this
      // time (although not incorrect)
      for (Address mbr : mbrs) {
        if (!members.contains(mbr)) members.add(mbr);
      }
    }

    ViewId tmp_vid = gms.getViewId();
    if (tmp_vid != null) tmp_vid = tmp_vid.copy();
    if (tmp_vid == null) throw new Exception("view ID is null; cannot return merge response");

    View view = new View(tmp_vid, new ArrayList<Address>(members));

    // [JGRP-524] - FLUSH and merge: flush doesn't wrap entire merge process
    // [JGRP-770] - Concurrent startup of many channels doesn't stabilize
    // [JGRP-700] - FLUSH: flushing should span merge

    /*if flush is in stack, let this coordinator flush its cluster island */
    if (gms.flushProtocolInStack && !gms.startFlush(view)) throw new Exception("flush failed");

    // we still need to fetch digests from all members, and not just return our own digest
    // (https://issues.jboss.org/browse/JGRP-948)
    Digest digest = fetchDigestsFromAllMembersInSubPartition(members, merge_id);
    if (digest == null || digest.size() == 0)
      throw new Exception(
          "failed fetching digests from subpartition members; dropping merge response");

    sendMergeResponse(sender, view, digest, merge_id);
  }
Exemple #11
0
  public static void testReadLine() throws IOException {
    final String input = "   hello world\nthis is \r\n just an example\r\nthis is line 2 \r\n";
    String line;
    InputStream in = new BufferedInputStream(new ByteArrayInputStream(input.getBytes()));
    List<String> list = new ArrayList<>(4);

    for (int i = 0; i < 4; i++) {
      line = Util.readLine(in);
      System.out.println("line = \"" + line + "\"");
      list.add(line);
    }

    assert list.size() == 4;
  }
Exemple #12
0
    /**
     * Merge all MergeData. All MergeData elements should be disjunct (both views and digests).
     * However, this method is prepared to resolve duplicate entries (for the same member).
     * Resolution strategy for views is to merge only 1 of the duplicate members. Resolution
     * strategy for digests is to take the higher seqnos for duplicate digests.
     *
     * <p>After merging all members into a Membership and subsequent sorting, the first member of
     * the sorted membership will be the new coordinator. This method has a lock on merge_rsps.
     *
     * @param merge_rsps A list of MergeData items. Elements with merge_rejected=true were removed
     *     before. Is guaranteed not to be null and to contain at least 1 member.
     */
    private MergeData consolidateMergeData(List<MergeData> merge_rsps) {
      long logical_time = 0; // for new_vid
      List<View> subgroups =
          new ArrayList<View>(11); // contains a list of Views, each View is a subgroup
      Collection<Collection<Address>> sub_mbrships = new ArrayList<Collection<Address>>();

      for (MergeData tmp_data : merge_rsps) {
        View tmp_view = tmp_data.getView();
        if (tmp_view != null) {
          ViewId tmp_vid = tmp_view.getVid();
          if (tmp_vid != null) {
            // compute the new view id (max of all vids +1)
            logical_time = Math.max(logical_time, tmp_vid.getId());
          }
          // merge all membership lists into one (prevent duplicates)
          sub_mbrships.add(new ArrayList<Address>(tmp_view.getMembers()));
          subgroups.add(tmp_view.copy());
        }
      }

      // determine the new digest
      Digest new_digest = consolidateDigests(merge_rsps, merge_rsps.size());
      if (new_digest == null) return null;

      // remove all members from the new member list that are not in the digest
      Collection<Address> digest_mbrs = new_digest.getMembers();
      for (Collection<Address> coll : sub_mbrships) coll.retainAll(digest_mbrs);

      List<Address> merged_mbrs = gms.computeNewMembership(sub_mbrships);

      // the new coordinator is the first member of the consolidated & sorted membership list
      Address new_coord = merged_mbrs.isEmpty() ? null : merged_mbrs.get(0);
      if (new_coord == null) return null;

      // should be the highest view ID seen up to now plus 1
      ViewId new_vid = new ViewId(new_coord, logical_time + 1);

      // determine the new view
      MergeView new_view = new MergeView(new_vid, merged_mbrs, subgroups);

      if (log.isTraceEnabled())
        log.trace(
            gms.local_addr
                + ": consolidated view="
                + new_view
                + "\nconsolidated digest="
                + new_digest);
      return new MergeData(gms.local_addr, new_view, new_digest);
    }
Exemple #13
0
  public static void testLeftMembers2() {
    final Address a = Util.createRandomAddress(),
        b = Util.createRandomAddress(),
        c = Util.createRandomAddress(),
        d = Util.createRandomAddress();

    List<Address> v1 = new ArrayList<>();
    v1.add(a);
    v1.add(b);
    v1.add(c);
    v1.add(d);

    List<Address> v2 = new ArrayList<>();
    v2.add(c);
    v2.add(d);
    v2.add(a);
    v2.add(b);

    View one = new View(new ViewId(a, 1), v1), two = new View(new ViewId(b, 2), v2);
    List<Address> left = View.leftMembers(one, two);
    System.out.println("left = " + left);
    assert left != null;
    assert left.isEmpty();
  }
Exemple #14
0
  public static void testPickNext() {
    List<Integer> list = new ArrayList<>(10);
    for (int i = 0; i < 10; i++) list.add(i);
    Integer num = Util.pickNext(list, 5);
    System.out.println("number next to 5: " + num);
    assert num != null;
    assert num.equals(6);

    num = Util.pickNext(list, 9);
    System.out.println("number next to 9: " + num);
    assert num != null;
    assert num.equals(0);

    num = Util.pickNext(list, 11);
    assert num == null;
  }
Exemple #15
0
  @ManagedOperation(description = "Reads data from local caches and dumps them to a file")
  public void dumpCache(String output_filename) throws Exception {
    Map<Address, PhysicalAddress> cache_contents =
        (Map<Address, PhysicalAddress>)
            down_prot.down(new Event(Event.GET_LOGICAL_PHYSICAL_MAPPINGS, false));

    List<PingData> list = new ArrayList<>(cache_contents.size());
    for (Map.Entry<Address, PhysicalAddress> entry : cache_contents.entrySet()) {
      Address addr = entry.getKey();
      PhysicalAddress phys_addr = entry.getValue();
      PingData data =
          new PingData(addr, true, UUID.get(addr), phys_addr).coord(addr.equals(local_addr));
      list.add(data);
    }
    OutputStream out = new FileOutputStream(output_filename);
    write(list, out);
  }
Exemple #16
0
  protected void startStack(String cluster_name) throws Exception {
    /*make sure the channel is not closed*/
    checkClosed();

    /*make sure we have a valid channel name*/
    if (cluster_name == null) log.debug("cluster_name is null, assuming unicast channel");
    else this.cluster_name = cluster_name;

    if (socket_factory != null) prot_stack.getTopProtocol().setSocketFactory(socket_factory);

    prot_stack.startStack(
        cluster_name, local_addr); // calls start() in all protocols, from top to bottom

    /*create a temporary view, assume this channel is the only member and is the coordinator*/
    List<Address> t = new ArrayList<>(1);
    t.add(local_addr);
    my_view = new View(local_addr, 0, t); // create a dummy view

    TP transport = prot_stack.getTransport();
    transport.registerProbeHandler(probe_handler);
  }
Exemple #17
0
    public void run() {
      long end_time, wait_time;
      List<Request> requests = new LinkedList<Request>();
      while (Thread.currentThread().equals(thread) && !suspended) {
        try {
          boolean keepGoing = false;
          end_time = System.currentTimeMillis() + max_bundling_time;
          do {
            Request firstRequest =
                (Request)
                    queue.remove(INTERVAL); // throws a TimeoutException if it runs into timeout
            requests.add(firstRequest);
            if (!view_bundling) break;
            if (queue.size() > 0) {
              Request nextReq = (Request) queue.peek();
              keepGoing = view_bundling && firstRequest.canBeProcessedTogether(nextReq);
            } else {
              wait_time = end_time - System.currentTimeMillis();
              if (wait_time > 0)
                queue.waitUntilClosed(
                    wait_time); // misnomer: waits until element has been added or q closed
              keepGoing =
                  queue.size() > 0 && firstRequest.canBeProcessedTogether((Request) queue.peek());
            }
          } while (keepGoing && System.currentTimeMillis() < end_time);

          try {
            process(requests);
          } finally {
            requests.clear();
          }
        } catch (QueueClosedException e) {
          break;
        } catch (TimeoutException e) {
          break;
        } catch (Throwable catchall) {
          Util.sleep(50);
        }
      }
    }
Exemple #18
0
    protected void handleMessage(Message msg) throws Exception {
      Address dest = msg.getDest();
      long len;
      List tmp;

      len = msg.size(); // todo: use msg.getLength() instead of msg.getSize()
      if (len > max_bundle_size) {
        throw new Exception(
            "UDP.BundlingOutgoingPacketHandler.handleMessage(): "
                + "message size ("
                + len
                + ") is greater than UDP fragmentation size. "
                + "Set the fragmentation/bundle size in FRAG and UDP correctly");
      }

      if (total_bytes + len >= max_bundle_size) {
        if (Trace.trace) {
          Trace.info(
              "UDP.BundlingOutgoingPacketHandler.handleMessage()",
              "sending " + total_bytes + " bytes");
        }
        bundleAndSend(); // send all pending message and clear table
        total_bytes = 0;
      }

      synchronized (msgs) {
        tmp = (List) msgs.get(dest);
        if (tmp == null) {
          tmp = new List();
          msgs.put(dest, tmp);
        }
        tmp.add(msg);
        total_bytes += len;
      }

      if (!timer_running) { // first message to be bundled
        startTimer();
      }
    }
Exemple #19
0
    public void addResponse(PingData rsp, boolean overwrite) {
      if (rsp == null) return;
      promise.getLock().lock();
      try {
        if (overwrite) ping_rsps.remove(rsp);

        // https://jira.jboss.org/jira/browse/JGRP-1179
        int index = ping_rsps.indexOf(rsp);
        if (index == -1) {
          ping_rsps.add(rsp);
          promise.getCond().signalAll();
        } else if (rsp.isCoord()) {
          PingData pr = ping_rsps.get(index);

          // Check if the already existing element is not server
          if (!pr.isCoord()) {
            ping_rsps.set(index, rsp);
            promise.getCond().signalAll();
          }
        }
      } finally {
        promise.getLock().unlock();
      }
    }
  protected <T> GroupRequest<T> cast(
      final Collection<Address> dests,
      Message msg,
      RequestOptions options,
      boolean block_for_results,
      FutureListener<RspList<T>> listener)
      throws Exception {
    if (msg.getDest() != null && !(msg.getDest() instanceof AnycastAddress))
      throw new IllegalArgumentException("message destination is non-null, cannot send message");

    if (options != null) {
      msg.setFlag(options.getFlags()).setTransientFlag(options.getTransientFlags());
      if (options.getScope() > 0) msg.setScope(options.getScope());
    }

    List<Address> real_dests;
    // we need to clone because we don't want to modify the original
    if (dests != null) {
      real_dests = new ArrayList<Address>();
      for (Address dest : dests) {
        if (dest instanceof SiteAddress || this.members.contains(dest)) {
          if (!real_dests.contains(dest)) real_dests.add(dest);
        }
      }
    } else real_dests = new ArrayList<Address>(members);

    // if local delivery is off, then we should not wait for the message from the local member.
    // therefore remove it from the membership
    Channel tmp = channel;
    if ((tmp != null && tmp.getDiscardOwnMessages())
        || msg.isTransientFlagSet(Message.TransientFlag.DONT_LOOPBACK)) {
      if (local_addr == null) local_addr = tmp != null ? tmp.getAddress() : null;
      if (local_addr != null) real_dests.remove(local_addr);
    }

    if (options != null && options.hasExclusionList()) {
      Address[] exclusion_list = options.exclusionList();
      for (Address excluding : exclusion_list) real_dests.remove(excluding);
    }

    // don't even send the message if the destination list is empty
    if (log.isTraceEnabled()) log.trace("real_dests=" + real_dests);

    if (real_dests.isEmpty()) {
      if (log.isTraceEnabled()) log.trace("destination list is empty, won't send message");
      return null;
    }

    if (options != null) {
      boolean async = options.getMode() == ResponseMode.GET_NONE;
      if (options.getAnycasting()) {
        if (async) async_anycasts.incrementAndGet();
        else sync_anycasts.incrementAndGet();
      } else {
        if (async) async_multicasts.incrementAndGet();
        else sync_multicasts.incrementAndGet();
      }
    }

    GroupRequest<T> req = new GroupRequest<T>(msg, corr, real_dests, options);
    if (listener != null) req.setListener(listener);
    if (options != null) {
      req.setResponseFilter(options.getRspFilter());
      req.setAnycasting(options.getAnycasting());
    }
    req.setBlockForResults(block_for_results);
    req.execute();
    return req;
  }
Exemple #21
0
  /**
   * Get the view and digest and send back both (MergeData) in the form of a MERGE_RSP to the
   * sender. If a merge is already in progress, send back a MergeData with the merge_rejected field
   * set to true.
   *
   * @param sender The address of the merge leader
   * @param merge_id The merge ID
   * @param mbrs The set of members from which we expect responses
   */
  public void handleMergeRequest(
      Address sender, MergeId merge_id, Collection<? extends Address> mbrs) {
    boolean success = matchMergeId(merge_id) || setMergeId(null, merge_id);
    if (!success) {
      if (log.isWarnEnabled()) log.warn(gms.local_addr + ": merge is already in progress");
      sendMergeRejectedResponse(sender, merge_id);
      return;
    }

    /* Clears the view handler queue and discards all JOIN/LEAVE/MERGE requests until after the MERGE  */
    gms.getViewHandler().suspend(merge_id);
    if (log.isDebugEnabled())
      log.debug(
          gms.local_addr
              + ": got merge request from "
              + sender
              + ", merge_id="
              + merge_id
              + ", mbrs="
              + mbrs);

    // merge the membership of the current view with mbrs
    List<Address> members = new LinkedList<Address>();
    if (mbrs
        != null) { // didn't use a set because we didn't want to change the membership order at this
                   // time (although not incorrect)
      for (Address mbr : mbrs) {
        if (!members.contains(mbr)) members.add(mbr);
      }
    }

    ViewId tmp_vid = gms.view_id != null ? gms.view_id.copy() : null;
    if (tmp_vid == null) {
      log.warn("view ID is null; cannot return merge response");
      sendMergeRejectedResponse(sender, merge_id);
      return;
    }
    View view = new View(tmp_vid, new Vector<Address>(members));

    // [JGRP-524] - FLUSH and merge: flush doesn't wrap entire merge process
    // [JGRP-770] - Concurrent startup of many channels doesn't stabilize
    // [JGRP-700] - FLUSH: flushing should span merge

    /*if flush is in stack, let this coordinator flush its cluster island */
    boolean successfulFlush = gms.startFlush(view);
    if (!successfulFlush) {
      sendMergeRejectedResponse(sender, merge_id);
      if (log.isWarnEnabled())
        log.warn(
            gms.local_addr
                + ": flush failed; sending merge rejected message to "
                + sender
                + ", merge_id="
                + merge_id);
      cancelMerge(merge_id);
      return;
    }
    Digest digest = fetchDigestsFromAllMembersInSubPartition(members);
    if (digest.size() == 0) {
      log.error("failed fetching digests from subpartition members; dropping merge response");
      return;
    }
    sendMergeResponse(sender, view, digest, merge_id);
  }
Exemple #22
0
 /**
  * Sets the new {@link AddressGenerator}. New addresses will be generated using the new generator.
  * This should <em>not</em> be done while a channel is connected, but before connecting.
  *
  * @param address_generator
  * @since 2.12
  */
 public void addAddressGenerator(AddressGenerator address_generator) {
   if (address_generator == null) return;
   if (address_generators == null) address_generators = new ArrayList<>(3);
   address_generators.add(address_generator);
 }
Exemple #23
0
  @SuppressWarnings("unchecked")
  public void testObjectToFromByteBuffer() throws Exception {
    byte[] buf;
    Address addr = Util.createRandomAddress(), addr2;
    List<String> list = new ArrayList<>(), list2;
    list.add("Bela");
    list.add("Jeannette");

    buf = Util.objectToByteBuffer(addr);
    addr2 = (Address) Util.objectFromByteBuffer(buf);
    System.out.println("addr=" + addr + ", addr2=" + addr2);
    Assert.assertEquals(addr, addr2);

    buf = Util.objectToByteBuffer(list);
    list2 = (List<String>) Util.objectFromByteBuffer(buf);
    System.out.println("list=" + list + ", list2=" + list2);
    Assert.assertEquals(list, list2);

    byte[] buffer = {'B', 'e', 'l', 'a', ' ', 'B', 'a', 'n'};
    buf = Util.objectToByteBuffer(buffer);

    byte[] buffer2 = (byte[]) Util.objectFromByteBuffer(buf);
    assert buffer2 != null && buffer.length == buffer2.length;
    assert Arrays.equals(buffer, buffer2);

    Object obj = null;
    buf = Util.objectToByteBuffer(obj);
    assert buf != null;
    assert buf.length > 0;
    obj = Util.objectFromByteBuffer(buf);
    assert obj == null;

    Object[] values = {
      Boolean.TRUE,
      true,
      false,
      Boolean.FALSE,
      (byte) 22,
      new Byte("2"),
      '5',
      3.14,
      352.3f,
      0,
      100,
      322649,
      Integer.MAX_VALUE,
      Integer.MIN_VALUE,
      0L,
      322649L,
      Long.MAX_VALUE - 50,
      Long.MAX_VALUE,
      Long.MIN_VALUE,
      (short) 22,
      Short.MAX_VALUE,
      Short.MIN_VALUE,
      "Bela Ban",
      new byte[] {'H', 'e', 'l', 'l', 'o'},
      Util.generateArray(1024)
    };
    for (int i = 0; i < values.length; i++) {
      Object value = values[i];
      marshal(value);
    }
  }