I have updated my code as follows:

ClassMethod test2() As %Status

{

    #Dim sigJOSE As %DynamicObject

    #Dim encJOSE As %DynamicObject

    #Dim claims As %DynamicObject

    Set ts = $ZTIMESTAMP  // 67161,81327.6633447

    Set exp = ##class(%OAuth2.Utils).TimeInSeconds(ts,300)

    Set nbf = ##class(%OAuth2.Utils).TimeInSeconds(ts,0)

    Set iat = ##class(%OAuth2.Utils).TimeInSeconds(ts,0)

    Set sigJOSE = {}

    Set sigJOSE.alg = "RS384"

    Set sigJOSE.typ = "JWT"

    Set header = sigJOSE.%ToJSON()

    Set claims = {}

    Set claims.iss = "863e73c5-9839-4b54-8205-c9404d2bb762"

    Set claims.sub = claims.iss

    Set claims.aud = "https://fhir.epic.com/interconnect-fhir-oauth/oauth2/token"

    Set claims.jti = "f9eaafba-2e49-11ea-8880-5ce0c5aee679"

    Set claims.exp = exp

    Set claims.nbf = nbf

    Set claims.iat = iat

    Set payload = claims.%ToJSON()

    //Set sigJWKS = ..MyKeys()

    //Set encJWKS = ""

    //Set tSC = ##class(%Net.JSON.JWT).Create(sigJOSE,{},claims,sigJWKS,encJWKS,.JWT)

    //Do $System.Status.DisplayError(tSC)

    Set bitLength = 384

    Set flags = 0

    Set tData = ##class(%SYSTEM.Encryption).Base64Encode(header,flags)_"."_##class(%SYSTEM.Encryption).Base64Encode(payload,flags)

    Set key = ..PrivateKey()

    //Set privKeyPassword = ""

    Set signature = ##class(%SYSTEM.Encryption).RSASHA3Sign(bitLength, tData, key)

    Set jwt = tData_"."_##class(%SYSTEM.Encryption).Base64Encode(signature,flags)

    Set pad = "="

    Set jwt = $Translate(jwt,pad,"")

    Set delim = $Char(13,10)

    For ii = 1:1:$Length(jwt,delim) {

        Write $Piece(jwt,delim,ii),!

    }

    Quit jwt

}

I have seen files transferred inside JSON and I want to try it here. Before (now) I have this code to generate response object:

Set context.Response = ""
 If 1=request.%IsA("EnsLib.HTTP.GenericMessage") {
   If (context.StatusLine = "") {
      Set context.StatusLine = "HTTP/1.1 200 OK"
   }
   If (##class(%File).Exists(context.Outputfile)) {
     Set tStream = ##class(%Stream.FileBinary).%New()
     Set tSC = tStream.LinkToFile(context.Outputfile)
     If $$$ISERR(tSC) Do ##class(Oliver.Util).DebugStatus(tSC)
   }

   //Set tSC = tmp.%Save()
   Set context.Response=##class(EnsLib.HTTP.GenericMessage).%New($Get(tStream),,request.HTTPHeaders)
   Do context.Response.HTTPHeaders.SetAt("application/pdf","Content-Type")
   Do context.Response.HTTPHeaders.SetAt(context.StatusLine,"StatusLine")
   Set tSC = context.Response.%Save()
 }

I did a search for STRINGSTACK. Then I was able to solve this issue by changing Write param.%ToJSON() to Do param.%ToJSON()

This is in Docs for %ToJSON():

method %ToJSON(outstrm As %Stream.Object) as %String

Convert a %DynamicAbstractObject into a JSON string.

outstrm is optional. There are a number of possibilities:
(1) Parameter outstrm is not defined and the method is called via 'DO'. In this case the JSON string is written to the current output device.
(2) Parameter outstrm is not defined and the method is called as an expression. In this case the JSON string becomes the value of the expression.
(3) Parameter outstrm is defined. If it is %Stream object then the JSON string will be written to the stream. If outstrm is present but not an object then it is presumed to be a fully qualified file specification. In that case, a %Stream.FileCharacter stream is created, linked to that file and the JSON string is written to that stream. On completion, this stream is saved. The full path to the file must be defined. If outstrm is an object but is not an instance of %Stream.Object then an exception will be thrown.