code: static void setTraceSpec(TraceSpecification spec) {
          if (spec == null)
              return;
  
          // We must have the lock to proceed
          allTraceComponentsLock.lock();
          try {
              // Since we have the lock, we must process any new trace components and
              // if we do it now, those new components will also get the trace spec given to them.
              processNewTraceComponents();
  
              if (activeTraceSpec != null && activeTraceSpec.equals(spec)) {
                  // equivalent trace specification -- nothing to do here.
                  return;
              }
              activeTraceSpec = spec;
  
              // update all of the current trace components
              for (TraceComponent t : allTraceComponents) {
                  t.setTraceSpec(activeTraceSpec);
              }
              // Update the static flag for whether or not any trace is enabled
              // no guarantee about when threads will see this update..  
              TraceComponent.setAnyTracingEnabled(activeTraceSpec.isAnyTraceEnabled());
  
              // Log the new trace level. This is done after updating TCs to
              // ensure the message goes to trace.log as necessary.
              // =enabled is redundant, and apparently discouraged, so we hide it for message display.
              Tr.info(TraceSpecification.getTc(), "MSG_TRACE_STATE_CHANGED", activeTraceSpec.toDisplayString());
  
              // Okay as that processing could have taken some time, we need to catch any new
              // trace components that might have appeared (which does leave a tiny window, but that
              // will either be caught on the next setTraceSpec or never processed (because we never
              // needed it).
              processNewTraceComponents();
          } finally {
              allTraceComponentsLock.unlock();
          }
      }
docs: package-private: Set the trace specification of the service to the input
  value.
  
  @param spec