Introdução ao Byteman
Filippe Spolti
Software Engineer - Red Hat
Resolvendo o problema
RULE setRequestsRecovery
CLASS org.jbpm.process.core.timer.impl.QuartzSchedulerService
METHOD internalSchedule
AT WRITE $jobq
IF TRUE
DO
traceln("[BYTEMAN] Current Value for requestsRecovery: " + $jobq.requestsRecovery() +
" ---------- UPDATING");
$jobq.setRequestsRecovery(true);
traceln("[BYTEMAN] New value for requestsRecovery: " + $jobq.requestsRecovery());
ENDRULE
Primeiros Passos
• Como Ativar o Byteman?
• -javaagent:/$BYTEMAN_HOME/lib/byteman.jar=script:$BYTEMAN_HOME/scripts/MyCo
olScript.btm
• sys - Adiciona o byteman ao System classloader.
• boot - Adiciona o byteman ao bootstrap classloader.
• Load/Unload Byteman em Runtime
• bminstall.sh - Cuidado!
• bmsubmit.sh - Load/Unload de Scripts Byteman.
• Integrações
• Principais framework de testes: Junit e TestNG.
• Maven/ant (Annotations).
• Validando o script
• bmcheck.sh
ECA - Event Conditions Action
• Where (onde)
• CLASS java.lang.Thread
• METHOD start()
• AT ENTRY
• Whether (se)
• IF true
• What (Qual)
• DO traceln("*** Hello TDC POA ***")
Esqueleto do Script Byteman
RULE @X regra feliz
COMPILE|NOCOMPILE (Opcional)
CLASS|INTERFACE br.com.tdcpoa.MinhaClasseLegal
METHOD NaoMeModifique (Para construtores <init>)
HELPER br.com.tdcpoa.MeuAjudanteNota10 (Opcional)
AT WRITE $objetoA (Opcional)
BIND nome:type = valor (Opcional)
feliz:boolean = $objetoA.Feliz();
IF feliz == true
DO //faça algo legal
minhaOperacaoBuiltInParaImprimir(“Feliz“);
ENDRULE - Fim da definição da regra
Especificadores de Localização
AT ENTRY AFTER INVOKE [ type .] method [ ( argtypes ) ][count | ALL ]
AT EXIT AT SYNCHRONIZE [count | ALL ]
AT LINE number AFTER SYNCHRONIZE [count | ALL ]
AT READ [type .] field [count | ALL ] AT THROW [count | ALL ]
AT READ $var-or-idx [count | ALL ] AT EXCEPTION EXIT
AFTER READ [ type .] field [count | ALL ]
AFTER READ $var-or-idx [count | ALL ]
AT WRITE [ type .] field [count | ALL ]
AT WRITE $var-or-idx [count | ALL ]
AFTER WRITE [ type .] field [count | ALL ]
AFTER WRITE $var-or-idx [count | ALL ]
AT INVOKE [ type .] method [ ( argtypes ) ] [count | ALL ]
O que é um Helper?
• Auxiliar
• Helper.java
• Subdivido em três categorias:
• coordenação de threads
• Gerenciamento do ciclo de vida das regras
• Debug e Tracing
import org.jboss.byteman.rule.helper.Helper;
public class MeuAjudanteNota10 extends Helper {
public void printHello(){
System.out.println(“Hello TDC POA);
}
}
Expressões de Referência
$!, $^, $#, $*, $@, $CLASS e $METHOD
$0, $1, $x, $this
CLASS ^javax.naming.InitialContext
Operadores
OR (||), LE (< =), NE (!=) TIMES (*) MINUS (-)
AND (&&), LT (<) GE (>=) DIVIDE (/) MOD (%)
NOT (!), EQ (==), GT (>) PLUS (+)
Principais Expressões
Compilar ou Interpretar as regras?
● Interpretadas
● Vale a pena?
● Quando usar regras compiladas?
● org.jboss.byteman.compile.to.bytecode
ClassNotFound?
● IMPORTS
● JBoss Modules
● OSGI e JigSaw (java 9)
BMunit
Código Java
@RunWith(org.jboss.byteman.contrib.bmunit.BMUnitRunner.class)
@BMUnitConfig(loadDirectory="target/test-classes")
@BMScript(value="check.btm")
public class MavenBMUnitTest {
@Test
...
}
A regra:
RULE check head
CLASS WebWriter
METHOD makeHeader
AT EXIT
BIND result = $builder.toString()
IF (NOT result.contains("<HEAD>") || NOT result.contains("</HEAD>"))
DO
THROW new RuntimeException("Header Inválido, Byteman got you. :)");
ENDRULE
Verificando Regras
• Sempre verifique
• Livre de erros e warnings
• bmcheck
• bmcheck.sh -p br.com.tdcpoa -cp .
../../src/test/resources/check.btm
• maven
• configurar plugin byteman-rulecheck-maven-plugin
Ativando o Byteman no WildFly 10!
• Arquivos standalone.conf e domain.conf
if [ "x$JBOSS_MODULES_SYSTEM_PKGS" = "x" ]; then
JBOSS_MODULES_SYSTEM_PKGS="org.jboss.byteman"
fi
Modo Standalone:
JAVA_OPTS="$JAVA_OPTS
-javaagent:$BYTEMAN_HOME/lib/byteman.jar=script:/dados/presentations/byteman/demo/byteman-web-app/src/resources/th
read.btm,boot:$BYTEMAN_HOME/lib/byteman.jar,boot:/dados/presentations/byteman/demo/byteman-helper/target/byteman-
helper-1.0-SNAPSHOT.jar -Dorg.jboss.byteman.transform.all"
Domain:
<jvm-options>
<option
value="-javaagent:/${jboss.home.dir}/byteman/lib/byteman.jar=script:${jboss.home.dir}/byteman/scripts/org.jboss.re
moting3.EndpointImpl.btm,boot:${jboss.home.dir}/byteman/lib/byteman.jar"/>
<option value="-Dorg.jboss.byteman.transform.all=true"/>
</jvm-options>
Trabalhando com Regras em Runtime
● Instalando o byteman em uma JVM em execução:
> bminstall.sh 13101
> bminstall.sh -b -Dorg.jboss.byteman.transform.all
$JBOSS_HOME/jboss-modules.jar
● Carregando regras em runtime:
> bmsubmit.sh -l thread.btm
Descarregando regras:
> bmsubmit.sh -u thread.btm
Opções disponíveis do agente java
script:scriptfile
resourcescript:scriptfile
listener:boolean
port:portnum
address:host
manager:classname
modules:classname
sys:jarfile
boot:jarfile
policy:boolean
prop:name=value
Opções extra de configuração
Algumas configurações avançadas
• org.jboss.byteman.compileToBytecode
• org.jboss.byteman.dump.generated.classes
• org.jboss.byteman.dump.generated.classes.directory
• org.jboss.byteman.dump.generated.classes.intermediate
• org.jboss.byteman.debug
• org.jboss.byteman.transform.all
• org.jboss.byteman.skip.overriding.rules
• org.jboss.byteman.allow.config.updates
• org.jboss.byteman.sysprops.strict
Exemplo de Configuração
JAVA_OPTS="$JAVA_OPTS
-javaagent:$BYTEMAN_HOME/lib/byteman.jar=script:/dados/presentations/byteman/demo/byteman-web-app/s
rc/resources/rule.btm,boot:$BYTEMAN_HOME/lib/byteman.jar,boot:/dados/presentations/byteman/demo/byte
man-helper/target/byteman-helper-1.0-SNAPSHOT.jar -Dorg.jboss.byteman.transform.all"
Detalhando:
● -javaagent:/$BYTEMAN_HOME/lib/byteman.jar
○ É responsável por ativar o Byteman, Qualquer coisa depois do ‘=’ são as configurações do Byteman
separadas por vírgula.
● script:$BYTEMAN_HOME/scripts/script.btm
○ /dados/presentations/byteman/demo/byteman-web-app/src/resources/thread.btm
● boot:$BYTEMAN_HOME/lib/byteman.jar
○ diz ao Byteman que ele deve ser carregado no classloader bootstrap para acessar até classes da JVM.
● boot:$BYTEMAN_HOME/lib/byteman-helpers.jar
○ Define o helper no classloader bootstrap.
QuickStarts e tutoriais
● https://developer.jboss.org/wiki/FaultInjectionTestingWithByteman
● $BYTEMAN_HOME/contrib
● https://developer.jboss.org/wiki/BMUnitUsingBytemanWithJUnitOrTestNGFr
omMavenAndAnt
● https://developer.jboss.org/wiki/CheckingYourBytemanRuleScriptsUnderMav
en
● https://developer.jboss.org/wiki/FaultInjectionTestingWithByteman
● https://developer.jboss.org/wiki/BMUnitUsingBytemanWithJUnitOrTestNGFr
omMavenAndAnt#how_do_i_inject_trace_into_junit_tests
Demonstração
That’s it Folks
Obrigado!
http://byteman.jboss.org/
https://github.com/bytemanproject/byteman
IRC - Servidor: freenode - Canal: #byteman
https://www.gitbook.com/book/jboss-books/byteman-guia-do-programador/details
https://www.gitbook.com/@jboss-books/
https://github.com/jbug-brasil/byteman-repo
Telegram - Grupo JBug Brasil
IRC - Servidor: freenode - Canal: #jbug-brasil

TDC2016POA | Trilha Java - Introdução ao Byteman

  • 1.
    Introdução ao Byteman FilippeSpolti Software Engineer - Red Hat
  • 3.
    Resolvendo o problema RULEsetRequestsRecovery CLASS org.jbpm.process.core.timer.impl.QuartzSchedulerService METHOD internalSchedule AT WRITE $jobq IF TRUE DO traceln("[BYTEMAN] Current Value for requestsRecovery: " + $jobq.requestsRecovery() + " ---------- UPDATING"); $jobq.setRequestsRecovery(true); traceln("[BYTEMAN] New value for requestsRecovery: " + $jobq.requestsRecovery()); ENDRULE
  • 4.
    Primeiros Passos • ComoAtivar o Byteman? • -javaagent:/$BYTEMAN_HOME/lib/byteman.jar=script:$BYTEMAN_HOME/scripts/MyCo olScript.btm • sys - Adiciona o byteman ao System classloader. • boot - Adiciona o byteman ao bootstrap classloader. • Load/Unload Byteman em Runtime • bminstall.sh - Cuidado! • bmsubmit.sh - Load/Unload de Scripts Byteman. • Integrações • Principais framework de testes: Junit e TestNG. • Maven/ant (Annotations). • Validando o script • bmcheck.sh
  • 5.
    ECA - EventConditions Action • Where (onde) • CLASS java.lang.Thread • METHOD start() • AT ENTRY • Whether (se) • IF true • What (Qual) • DO traceln("*** Hello TDC POA ***")
  • 6.
    Esqueleto do ScriptByteman RULE @X regra feliz COMPILE|NOCOMPILE (Opcional) CLASS|INTERFACE br.com.tdcpoa.MinhaClasseLegal METHOD NaoMeModifique (Para construtores <init>) HELPER br.com.tdcpoa.MeuAjudanteNota10 (Opcional) AT WRITE $objetoA (Opcional) BIND nome:type = valor (Opcional) feliz:boolean = $objetoA.Feliz(); IF feliz == true DO //faça algo legal minhaOperacaoBuiltInParaImprimir(“Feliz“); ENDRULE - Fim da definição da regra
  • 7.
    Especificadores de Localização ATENTRY AFTER INVOKE [ type .] method [ ( argtypes ) ][count | ALL ] AT EXIT AT SYNCHRONIZE [count | ALL ] AT LINE number AFTER SYNCHRONIZE [count | ALL ] AT READ [type .] field [count | ALL ] AT THROW [count | ALL ] AT READ $var-or-idx [count | ALL ] AT EXCEPTION EXIT AFTER READ [ type .] field [count | ALL ] AFTER READ $var-or-idx [count | ALL ] AT WRITE [ type .] field [count | ALL ] AT WRITE $var-or-idx [count | ALL ] AFTER WRITE [ type .] field [count | ALL ] AFTER WRITE $var-or-idx [count | ALL ] AT INVOKE [ type .] method [ ( argtypes ) ] [count | ALL ]
  • 8.
    O que éum Helper? • Auxiliar • Helper.java • Subdivido em três categorias: • coordenação de threads • Gerenciamento do ciclo de vida das regras • Debug e Tracing import org.jboss.byteman.rule.helper.Helper; public class MeuAjudanteNota10 extends Helper { public void printHello(){ System.out.println(“Hello TDC POA); } }
  • 9.
    Expressões de Referência $!,$^, $#, $*, $@, $CLASS e $METHOD $0, $1, $x, $this CLASS ^javax.naming.InitialContext Operadores OR (||), LE (< =), NE (!=) TIMES (*) MINUS (-) AND (&&), LT (<) GE (>=) DIVIDE (/) MOD (%) NOT (!), EQ (==), GT (>) PLUS (+) Principais Expressões
  • 10.
    Compilar ou Interpretaras regras? ● Interpretadas ● Vale a pena? ● Quando usar regras compiladas? ● org.jboss.byteman.compile.to.bytecode ClassNotFound? ● IMPORTS ● JBoss Modules ● OSGI e JigSaw (java 9)
  • 11.
    BMunit Código Java @RunWith(org.jboss.byteman.contrib.bmunit.BMUnitRunner.class) @BMUnitConfig(loadDirectory="target/test-classes") @BMScript(value="check.btm") public classMavenBMUnitTest { @Test ... } A regra: RULE check head CLASS WebWriter METHOD makeHeader AT EXIT BIND result = $builder.toString() IF (NOT result.contains("<HEAD>") || NOT result.contains("</HEAD>")) DO THROW new RuntimeException("Header Inválido, Byteman got you. :)"); ENDRULE
  • 12.
    Verificando Regras • Sempreverifique • Livre de erros e warnings • bmcheck • bmcheck.sh -p br.com.tdcpoa -cp . ../../src/test/resources/check.btm • maven • configurar plugin byteman-rulecheck-maven-plugin
  • 13.
    Ativando o Bytemanno WildFly 10! • Arquivos standalone.conf e domain.conf if [ "x$JBOSS_MODULES_SYSTEM_PKGS" = "x" ]; then JBOSS_MODULES_SYSTEM_PKGS="org.jboss.byteman" fi Modo Standalone: JAVA_OPTS="$JAVA_OPTS -javaagent:$BYTEMAN_HOME/lib/byteman.jar=script:/dados/presentations/byteman/demo/byteman-web-app/src/resources/th read.btm,boot:$BYTEMAN_HOME/lib/byteman.jar,boot:/dados/presentations/byteman/demo/byteman-helper/target/byteman- helper-1.0-SNAPSHOT.jar -Dorg.jboss.byteman.transform.all" Domain: <jvm-options> <option value="-javaagent:/${jboss.home.dir}/byteman/lib/byteman.jar=script:${jboss.home.dir}/byteman/scripts/org.jboss.re moting3.EndpointImpl.btm,boot:${jboss.home.dir}/byteman/lib/byteman.jar"/> <option value="-Dorg.jboss.byteman.transform.all=true"/> </jvm-options>
  • 14.
    Trabalhando com Regrasem Runtime ● Instalando o byteman em uma JVM em execução: > bminstall.sh 13101 > bminstall.sh -b -Dorg.jboss.byteman.transform.all $JBOSS_HOME/jboss-modules.jar ● Carregando regras em runtime: > bmsubmit.sh -l thread.btm Descarregando regras: > bmsubmit.sh -u thread.btm
  • 15.
    Opções disponíveis doagente java script:scriptfile resourcescript:scriptfile listener:boolean port:portnum address:host manager:classname modules:classname sys:jarfile boot:jarfile policy:boolean prop:name=value
  • 16.
    Opções extra deconfiguração Algumas configurações avançadas • org.jboss.byteman.compileToBytecode • org.jboss.byteman.dump.generated.classes • org.jboss.byteman.dump.generated.classes.directory • org.jboss.byteman.dump.generated.classes.intermediate • org.jboss.byteman.debug • org.jboss.byteman.transform.all • org.jboss.byteman.skip.overriding.rules • org.jboss.byteman.allow.config.updates • org.jboss.byteman.sysprops.strict
  • 17.
    Exemplo de Configuração JAVA_OPTS="$JAVA_OPTS -javaagent:$BYTEMAN_HOME/lib/byteman.jar=script:/dados/presentations/byteman/demo/byteman-web-app/s rc/resources/rule.btm,boot:$BYTEMAN_HOME/lib/byteman.jar,boot:/dados/presentations/byteman/demo/byte man-helper/target/byteman-helper-1.0-SNAPSHOT.jar-Dorg.jboss.byteman.transform.all" Detalhando: ● -javaagent:/$BYTEMAN_HOME/lib/byteman.jar ○ É responsável por ativar o Byteman, Qualquer coisa depois do ‘=’ são as configurações do Byteman separadas por vírgula. ● script:$BYTEMAN_HOME/scripts/script.btm ○ /dados/presentations/byteman/demo/byteman-web-app/src/resources/thread.btm ● boot:$BYTEMAN_HOME/lib/byteman.jar ○ diz ao Byteman que ele deve ser carregado no classloader bootstrap para acessar até classes da JVM. ● boot:$BYTEMAN_HOME/lib/byteman-helpers.jar ○ Define o helper no classloader bootstrap.
  • 18.
    QuickStarts e tutoriais ●https://developer.jboss.org/wiki/FaultInjectionTestingWithByteman ● $BYTEMAN_HOME/contrib ● https://developer.jboss.org/wiki/BMUnitUsingBytemanWithJUnitOrTestNGFr omMavenAndAnt ● https://developer.jboss.org/wiki/CheckingYourBytemanRuleScriptsUnderMav en ● https://developer.jboss.org/wiki/FaultInjectionTestingWithByteman ● https://developer.jboss.org/wiki/BMUnitUsingBytemanWithJUnitOrTestNGFr omMavenAndAnt#how_do_i_inject_trace_into_junit_tests
  • 19.
  • 20.
    That’s it Folks Obrigado! http://byteman.jboss.org/ https://github.com/bytemanproject/byteman IRC- Servidor: freenode - Canal: #byteman https://www.gitbook.com/book/jboss-books/byteman-guia-do-programador/details https://www.gitbook.com/@jboss-books/ https://github.com/jbug-brasil/byteman-repo Telegram - Grupo JBug Brasil IRC - Servidor: freenode - Canal: #jbug-brasil