SlideShare ist ein Scribd-Unternehmen logo
1 von 51
Downloaden Sie, um offline zu lesen
1
Power Tools in Java SDK
Elek Márton
DPC Consulting Kft
2
• Modular static html site generator
• (like Jekyll, github pages)
• Do custom transformation on each text file
• Example transformations:
• ascii link break → <br/>
• plain text → text with html header/footer
<html>....<body>{...}</body></html>
Example application
3
Code example – types
public class Resource {
private Map<String, String> headers = new HashMap<>();
private String content;
…
}
public interface Transformer {
public void transform(Resource resource);
}
4
Code example – processing
System.out.println("Transforming " + file);
Resource r = new Resource(new String(Files.readAllBytes(file)));
for (Transformer transformations : transformers) {
transformations.transform(r);
}
return r;
5
Modularity
6
• Kezdeti megoldás:
private List<Transformer> transformations = new ArrayList();
public Generator() {
transformations.add(new HtmlFrameTransformator());
transformations.add(new Nl2BrTransfomer());
}
for (Transformer transformations : transformers) {
transformations.transform(r);
}
• Cél
• Dinamikusan kiterjeszthető
• lib/-be új JAR → automatikusan elinduljon
Modularitás
7
Step one: using descriptors
• bin/
• site-generator.bat
• site-generator.sh
• lib/
• site-generator-1.0.jar
• site-generator-extension-1.0.jar
• config
• transform-implementations.cfg:
hu.dpc.javabar.powertools.impl.HtmlFrameTransformator
hu.dpc.javabar.powertools.impl.Nl2BrTransfomer
hu.dpc.javabar.powertools.impl.YoutubeTransformer
8
Step two: descriptor on
classpath
• bin/
• site-generator.bat, site-generator.sh
• lib/
• site-generator-1.0.jar
• site-generator-1.0.jar:/transform-implementations.cfg
hu.dpc.javabar.powertools.impl.HtmlFrameTransformator
hu.dpc.javabar.powertools.impl.Nl2BrTransfomer
• site-generator-extension-1.0.jar
• site-generator-extension-1.0.jar:/transform-implementations.cfg
hu.dpc.javabar.powertools.impl.YoutubeTransformer
Enumeration<URL> resources =
getClass().getClassLoader().getResources("/transform-implementations.cfg");
9
Step three:
Service Provider Interface
• Standard, part of the JDK
• Descriptor are on the classpath
• Contains the class names of the implementations
• Using nameconvention (META-INF/services/hu.dpc...Interface)
• Simple API (ServiceLoader), only a few classes
• Not included:
• Dependency management
• Versioning
• Priority handling
• Only answers the question:
• Who implemented a specific interface
10
SPI code example
• META-INF/services/hu.dpc.javabar.powertools.api.Transformer
• hu.dpc.javabar.powertools.impl.HtmlFrameTransformer
• hu.dpc.javabar.powertools.impl.Nl2BrTransfomer
ServiceLoader<Transformer> transformers =
ServiceLoader.load(Transformer.class);
for (Transformer transfomer : transformers) {
...
}
11
SPI – where is it used
• (almost) everywhere
• multiple location at JDK (eg. XML processor
implementation)
• Even the OSGi has adapter for SPI
• Very effective even if it's very simple
• Easy solution to avoid circular dependencies
of the projects
12
Automatic SPI generation
13
How to generate
SPI descriptors?
• Service Provider Interface
META-INF/services/...
should be created and filled with
implementation automatically
14
Annotation processors
• Part of the javac from Java 6
• Run at compile time
• Class/descriptor/... files could be generated
based on specific annotated classes
• Could be activated with SPI
• META-INF/services/
javax.annotation.processing.Processor
• Multiple iteration (processing the generated files)
• Parameters could be used
15
Annotation processor
public @interface Service {
}
@Service
public class Nl2BrTransfomer implements Transformer {
@Override
public void transform(Resource resource) {
resource.setContent(
resource.getContent().replaceAll("nn", "<br/>")
);
}
}
16
Annotation processor example
@SupportedAnnotationTypes("hu.dpc.javabar.powertools.Service")
@SupportedSourceVersion(SourceVersion.RELEASE_7)
public class ServiceAnnotationProcessor extends AbstractProcessor {
Map<String, Set<String>> services = new HashMap<String, Set<String>>();
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
…
}
}
17
Annotation processor example
Map<String, Set<String>> services = new HashMap<String, Set<String>>();
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "@service generation");
if (roundEnv.processingOver()) {
writeOutServices(roundEnv);
return false;
}
//process annotations
...
}
18
Annotation processor example
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
//write out the file
...
Elements elements = processingEnv.getElementUtils();
for (Element element : roundEnv.getElementsAnnotatedWith(Service.class)) {
TypeElement type = (TypeElement) element;
TypeElement contract = (TypeElement) ((DeclaredType) type.getInterfaces().get(0)).asElement();
String cn = elements.getBinaryName(contract).toString();
Set<String> v = services.get(cn);
if (v == null) {
services.put(cn, v = new TreeSet<String>());
}
v.add(cn);
}
return false;
}
19
Generating code
for (Element element : roundEnv.getElementsAnnotatedWith(Service.class)) {
TypeElement type = (TypeElement) element;
JavaFileObject jfo = processingEnv.getFiler().createSourceFile(
type.getQualifiedName() + "GeneratedInfo");
BufferedWriter bw = new BufferedWriter(jfo.openWriter());
bw.append("package ");
bw.append(((PackageElement) type.getEnclosingElement()).getQualifiedName());
bw.append(";n");
bw.append("import hu.dpc.javabar.powertools.Service;n");
bw.newLine();
bw.newLine();
bw.append("@Service n");
bw.append(String.format("public class %s{", type.getSimpleName()));
bw.newLine();
bw.append("public static final boolean PROCESSED = true;" );
bw.append("}");
bw.flush();
20
Project to generate SPI
• To generate SPI descriptors, try
• http://metainf-services.kohsuke.org/
• https://code.google.com/p/spi/
<dependency>
<groupId>org.kohsuke.metainf-services</groupId>
<artifactId>metainf-services</artifactId>
<version>1.1</version>
<optional>true</optional>
</dependency>
21
Runtime Javadoc access
22
Documentation of SPI
implementation
/**
* Replace new double new lines with html line break.
*/
@Service("Replace new double new lines with html line break")
public class Nl2BrTransfomer implements Transformer {
@Override
public void transform(Resource resource) {
resource.setContent(resource.getContent().replaceAll("nn", "<br/>"));
}
}
Available transformations:
HtmlFrameTransformator : ...
Nl2BrTransfomer : Replace new double new lines with html line break
23
How to access javadoc at
runtime?
>>> def hello(name):
... """Print hello for the name"""
... print("Hello", name)
...
>>> hello("Bela")
Hello Bela
>>> print(hello.__doc__)
Print hello for the name
user=> (defn hello "Print hello for
the name" [name] (str "Hello " name))
#'user/hello
user=> (hello "Bela")
"Hello Bela"
user=> (get (meta (var hello)) :doc)
"Print hello for the name"
• The documentation of the annotated service
class should come from javadoc documents
• Easy with other languages(Python, Clojure)
24
Javadoc – Doclets
• Formatting classes for custom javadoc
generation
• Doclet API could access all of the javadoc and
class metadata information
• Could be used to generate custom javadoc
page but also to generate XML descriptors
25
Doclet example
public class GenerateDocletResource {
public static boolean start(RootDoc rootDoc) {
for (ClassDoc cd : rootDoc.specifiedClasses()) {
Path p = Paths.get(root + "/.../" +
cd.qualifiedTypeName() + ".javadoc");
Files.createDirectories(p.getParent());
Files.write(p, cd.commentText().getBytes());
}
return true;
}
}
26
Doclet loading
public String getJavadoc(Class type) {
String resourceName = "/" + type.getCanonicalName() + ".javadoc";
try (InputStream s = getClass().getResourceAsStream(resourceName)){
if (s == null) {
return "Javadoc resource is missing for class " + type;
}
return new Scanner(s).useDelimiter("//Z").next();
} catch (IOException ex) {
...
}
}
27
Using it from Gradle
dependencies {
doclet project(":javadoc-metadata-generator")
}
task generateDocs(type: Javadoc) {
source = sourceSets.main.allJava
options = new SimpleJavadocOption()
options.docletpath = configurations.doclet.files.asType(List)
options.doclet = "hu.dpc.javabar.powertools.doc.GenerateDocletResource"
}
compileJava.dependsOn generateDocs
28
Using it from Maven
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<executions>
<execution>
<id>doc-resource-generator</id>
<phase>prepare-package</phase>
<goals>javadoc</goals>
</execution>
</executions>
<configuration>
<doclet>org.umlgraph.doclet.UmlGraphDoc</doclet>
<!-- <docletPath>/path/to/UmlGraph.jar</docletPath> -->
<docletArtifact>
<groupId>org.umlgraph</groupId>
<artifactId>doclet</artifactId>
<version>5.1</version>
</docletArtifact>
<additionalparam>-views</additionalparam>
<useStandardDocletOptions>true</useStandardDocletOptions>
</configuration>
</plugin>
29
Runtime metrics
30
Java Management Extension
(JMX)
• Well known solution from the Standard Java
API
• Management
• Monitoring
• All of the JVM information could be accessed
as well
• Custom metrics could be added
31
JMX JSR
• JSR 3: Java Management Extension (JMX)
• JSR 160: JMX Remote API
• JSR 255: JMX 2.0 = JSR 3 + 160 + …
(Inactive)
• JSR 262: Web Services Connector for JMX
(Inactive)
• Jolokia: REST interface adapter
32
JMX Architecture
Source wikipedia
33
JMX – Probe level
• MBean – Managed Object: bármilyen
resource
• Attributes
• Operations
• Notifications
• MBean types
• Standard
• Dynamic
• MXBeans
34
Simple JMX example
public interface GeneratorMBean {
public void stop();
public int getProcessedFileNo();
}
MBeanServer server =
ManagementFactory.getPlatformMBeanServer();
ObjectName name =
new ObjectName("hu.dpc.javabar.powertools", "name", "Generator");
server.registerMBean(generator, name);
//generator implements GeneratorMBean
35
JMX Architecture
Source wikipedia
36
JMX platform Mbean server
MBeanServer server =
ManagementFactory.getPlatformMBeanServer();
37
JMX custom Mbean server
MBeanServer server = MbeanServerFactory.createMBeanServer();
Registry registry = LocateRegistry.createRegistry(1234);
JMXServiceURL jmxServiceURL = new JMXServiceURL("rmi",
"localhost",
1235,
"/jndi/rmi://localhost:1234/jmx");
JMXConnectorServer connectorServer =
JMXConnectorServerFactory.newJMXConnectorServer(jmxServiceURL, null, server);
connectorServer.start();
System.out.println(jmxServiceURL);
// service:jmx:rmi://localhost:1235/jndi/rmi://localhost:1234/jmx
38
JMX client API
JMXServiceURL url =
new JMXServiceURL("service:jmx:rmi://localhost:1235/jndi/rmi://localhost:1234/jmx");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
ObjectName name = new ObjectName("hu.dpc.javabar.powertools", "name", "Generator");
GeneratorMBean mbean = JMX.newMBeanProxy(mbsc, name, GeneratorMBean.class);
System.out.println(mbean.getProcessedFileNo());
//12
39
JMX Architecture
Source wikipedia
40
JMX custom MBeanServer
MBeanServer server = MbeanServerFactory.createMBeanServer();
Registry registry = LocateRegistry.createRegistry(1234);
JMXServiceURL jmxServiceURL = new JMXServiceURL("rmi",
"localhost",
1235,
"/jndi/rmi://localhost:1234/jmx");
JMXConnectorServer connectorServer =
JMXConnectorServerFactory.newJMXConnectorServer(jmxServiceURL, null, server);
connectorServer.start();
System.out.println(jmxServiceURL);
// service:jmx:rmi://localhost:1235/jndi/rmi://localhost:1234/jmx
41
JMX platform MBeanServer
MBeanServer server =
ManagementFactory.getPlatformMBeanServer();
42
Agents
43
Java Agents
• Written in Java or C/C++
• Native: Java Virtual Machine Tool Interface (JVM TI)
• -agentlib, -agentpath
• Java:
• -javaagent
• Features
• run custom command (in the application JVM-ben)
• manipulating bytecode loading
• Activating
• Before application startup (-javaagent)
• Attaching at runtime (Attach API)
44
Java Agent interface
public static void premain(String agentArgs, Instrumentation inst) {
}
• Intstrumentation
• addTransformer(ClassFileTransformer transformer)
• Registers the supplied transformer.
• appendToBootstrapClassLoaderSearch(JarFile jarfile)
• Specifies a JAR file with instrumentation classes to be defined by the bootstrap class
loader.
• appendToSystemClassLoaderSearch(JarFile jarfile)
• Specifies a JAR file with instrumentation classes to be defined by the system class
loader
• ClassFileTransformer.
• transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer)
45
Activating Java Agent
• Before application start
• -javaagent:<jarpath>[=<options>]
• META-INF/MANIFEST.MF: Premain-Class: …
• public static void premain(...)
• During application run
• Attach API
• META-INF/MANIFEST.MF: Agent-Class: …
• public static void agentmain(...)
46
Attach API
//JVMs of the CURRENT user
List<VirtualMachineDescriptor> vms = VirtualMachine.list();
for (VirtualMachineDescriptor virtualMachineDescriptor : vms) {
VirtualMachine vm =
VirtualMachine.attach(virtualMachineDescriptor);
if (vm != null) {
System.out.println(virtualMachineDescriptor.displayName());
System.out.println("Java version = " +
vm.getSystemProperties().
getProperty("java.version"));
}
}
47
JMX connection – with agents
static final String CONNECTOR_ADDRESS =
"com.sun.management.jmxremote.localConnectorAddress";
VirtualMachine vm = VirtualMachine.attach(id);
String connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);
if (connectorAddress == null) {
String agent = vm.getSystemProperties().getProperty("java.home") +
File.separator + "lib" + File.separator + "management-agent.jar";
vm.loadAgent(agent);
connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);
}
JMXServiceURL url = new JMXServiceURL(connectorAddress);
JMXConnector = JMXConnectorFactory.connect(url);
48
Where is it used?
• Bytecode manipulation
• AspectJ
• Spring
• Persistence frameworks
• BTrace
• premain/agent:
• jre/lib/management-agent.jar
49
Summary
• JDK Power tools
• Service Provider Interface – for modularity
• Annotation processors – compile time
processing
• Javadoc doclet – Javadoc (pre)processing
• JMX – runtime metrics, methods
• Agentek, Attach API – byte code manipulation,
runtime modification
50
Credits
• Thanks for the image authors:
• Container, Sandor Volenszki, Creative Commons
• Blueprint, Will Scullin, Creative Commons
• Robot, Avram Cheaney, Creative Commons
• Control Panel, Paul, Creative Commons
• PCB, Karl-Ludwig G. Poggemann, Creative
Commons
51
Elek Márton / DPC Consulting
marton.elek@dpc.hu
http://www.meetup.com/bpjavabar/

Weitere ähnliche Inhalte

Was ist angesagt?

A Tour of the Modern Java Platform
A Tour of the Modern Java PlatformA Tour of the Modern Java Platform
A Tour of the Modern Java PlatformVMware Tanzu
 
Simple REST with Dropwizard
Simple REST with DropwizardSimple REST with Dropwizard
Simple REST with DropwizardAndrei Savu
 
Maven and j unit introduction
Maven and j unit introductionMaven and j unit introduction
Maven and j unit introductionSergii Fesenko
 
NetflixOSS season 2 episode 2 - Reactive / Async
NetflixOSS   season 2 episode 2 - Reactive / AsyncNetflixOSS   season 2 episode 2 - Reactive / Async
NetflixOSS season 2 episode 2 - Reactive / AsyncRuslan Meshenberg
 
Introducing Workflow Architectures Using Grails - Greach 2015
Introducing Workflow Architectures Using Grails - Greach 2015Introducing Workflow Architectures Using Grails - Greach 2015
Introducing Workflow Architectures Using Grails - Greach 2015Rubén Mondéjar Andreu
 
Spring5 New Features
Spring5 New FeaturesSpring5 New Features
Spring5 New FeaturesJay Lee
 
Weaving Through the Mesh: Making Sense of Istio and Overlapping Technologies
Weaving Through the Mesh: Making Sense of Istio and Overlapping TechnologiesWeaving Through the Mesh: Making Sense of Istio and Overlapping Technologies
Weaving Through the Mesh: Making Sense of Istio and Overlapping TechnologiesVMware Tanzu
 
Highlights from Java 10-13 and Future of Java at JCON 2019 by Alukhanov and K...
Highlights from Java 10-13 and Future of Java at JCON 2019 by Alukhanov and K...Highlights from Java 10-13 and Future of Java at JCON 2019 by Alukhanov and K...
Highlights from Java 10-13 and Future of Java at JCON 2019 by Alukhanov and K...Vadym Kazulkin
 
What's coming in Airflow 2.0? - NYC Apache Airflow Meetup
What's coming in Airflow 2.0? - NYC Apache Airflow MeetupWhat's coming in Airflow 2.0? - NYC Apache Airflow Meetup
What's coming in Airflow 2.0? - NYC Apache Airflow MeetupKaxil Naik
 
Petro Gordiievych "From Java 9 to Java 12"
Petro Gordiievych "From Java 9 to Java 12"Petro Gordiievych "From Java 9 to Java 12"
Petro Gordiievych "From Java 9 to Java 12"LogeekNightUkraine
 
Reactive Applications with Apache Pulsar and Spring Boot
Reactive Applications with Apache Pulsar and Spring BootReactive Applications with Apache Pulsar and Spring Boot
Reactive Applications with Apache Pulsar and Spring BootVMware Tanzu
 
Reactive Microservice And Spring5
Reactive Microservice And Spring5Reactive Microservice And Spring5
Reactive Microservice And Spring5Jay Lee
 

Was ist angesagt? (19)

A Tour of the Modern Java Platform
A Tour of the Modern Java PlatformA Tour of the Modern Java Platform
A Tour of the Modern Java Platform
 
Simple REST with Dropwizard
Simple REST with DropwizardSimple REST with Dropwizard
Simple REST with Dropwizard
 
Reactors.io
Reactors.ioReactors.io
Reactors.io
 
Maven and j unit introduction
Maven and j unit introductionMaven and j unit introduction
Maven and j unit introduction
 
NetflixOSS season 2 episode 2 - Reactive / Async
NetflixOSS   season 2 episode 2 - Reactive / AsyncNetflixOSS   season 2 episode 2 - Reactive / Async
NetflixOSS season 2 episode 2 - Reactive / Async
 
Introducing Workflow Architectures Using Grails - Greach 2015
Introducing Workflow Architectures Using Grails - Greach 2015Introducing Workflow Architectures Using Grails - Greach 2015
Introducing Workflow Architectures Using Grails - Greach 2015
 
Dropwizard
DropwizardDropwizard
Dropwizard
 
Spring5 New Features
Spring5 New FeaturesSpring5 New Features
Spring5 New Features
 
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter PilgrimJavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
 
Weaving Through the Mesh: Making Sense of Istio and Overlapping Technologies
Weaving Through the Mesh: Making Sense of Istio and Overlapping TechnologiesWeaving Through the Mesh: Making Sense of Istio and Overlapping Technologies
Weaving Through the Mesh: Making Sense of Istio and Overlapping Technologies
 
Highlights from Java 10-13 and Future of Java at JCON 2019 by Alukhanov and K...
Highlights from Java 10-13 and Future of Java at JCON 2019 by Alukhanov and K...Highlights from Java 10-13 and Future of Java at JCON 2019 by Alukhanov and K...
Highlights from Java 10-13 and Future of Java at JCON 2019 by Alukhanov and K...
 
What's coming in Airflow 2.0? - NYC Apache Airflow Meetup
What's coming in Airflow 2.0? - NYC Apache Airflow MeetupWhat's coming in Airflow 2.0? - NYC Apache Airflow Meetup
What's coming in Airflow 2.0? - NYC Apache Airflow Meetup
 
Petro Gordiievych "From Java 9 to Java 12"
Petro Gordiievych "From Java 9 to Java 12"Petro Gordiievych "From Java 9 to Java 12"
Petro Gordiievych "From Java 9 to Java 12"
 
Airflow and supervisor
Airflow and supervisorAirflow and supervisor
Airflow and supervisor
 
Reactive Applications with Apache Pulsar and Spring Boot
Reactive Applications with Apache Pulsar and Spring BootReactive Applications with Apache Pulsar and Spring Boot
Reactive Applications with Apache Pulsar and Spring Boot
 
AKS: k8s e azure
AKS: k8s e azureAKS: k8s e azure
AKS: k8s e azure
 
Reactive Microservice And Spring5
Reactive Microservice And Spring5Reactive Microservice And Spring5
Reactive Microservice And Spring5
 
JavaCro'14 - Unit testing in AngularJS – Slaven Tomac
JavaCro'14 - Unit testing in AngularJS – Slaven TomacJavaCro'14 - Unit testing in AngularJS – Slaven Tomac
JavaCro'14 - Unit testing in AngularJS – Slaven Tomac
 
Dropwizard
DropwizardDropwizard
Dropwizard
 

Ähnlich wie Power tools in Java

Object Graph Mapping with Spring Data Neo4j 3 - Nicki Watt & Michael Hunger @...
Object Graph Mapping with Spring Data Neo4j 3 - Nicki Watt & Michael Hunger @...Object Graph Mapping with Spring Data Neo4j 3 - Nicki Watt & Michael Hunger @...
Object Graph Mapping with Spring Data Neo4j 3 - Nicki Watt & Michael Hunger @...Neo4j
 
Metadata Extraction and Content Transformation
Metadata Extraction and Content TransformationMetadata Extraction and Content Transformation
Metadata Extraction and Content TransformationAlfresco Software
 
Devoxx08 - Nuxeo Core, JCR 2, CMIS
Devoxx08 - Nuxeo Core, JCR 2, CMIS Devoxx08 - Nuxeo Core, JCR 2, CMIS
Devoxx08 - Nuxeo Core, JCR 2, CMIS Nuxeo
 
Creating A Language Editor Using Dltk
Creating A Language Editor Using DltkCreating A Language Editor Using Dltk
Creating A Language Editor Using DltkKaniska Mandal
 
Global objects in Node.pdf
Global objects in Node.pdfGlobal objects in Node.pdf
Global objects in Node.pdfSudhanshiBakre1
 
Building Restful Web Services with Java
Building Restful Web Services with JavaBuilding Restful Web Services with Java
Building Restful Web Services with JavaVassil Popovski
 
ApacheCon NA 2015 Spark / Solr Integration
ApacheCon NA 2015 Spark / Solr IntegrationApacheCon NA 2015 Spark / Solr Integration
ApacheCon NA 2015 Spark / Solr Integrationthelabdude
 
Dart structured web apps
Dart   structured web appsDart   structured web apps
Dart structured web appschrisbuckett
 
Creating web applications with LODSPeaKr
Creating web applications with LODSPeaKrCreating web applications with LODSPeaKr
Creating web applications with LODSPeaKrAlvaro Graves
 
Introducing Node.js in an Oracle technology environment (including hands-on)
Introducing Node.js in an Oracle technology environment (including hands-on)Introducing Node.js in an Oracle technology environment (including hands-on)
Introducing Node.js in an Oracle technology environment (including hands-on)Lucas Jellema
 
Ingesting and Manipulating Data with JavaScript
Ingesting and Manipulating Data with JavaScriptIngesting and Manipulating Data with JavaScript
Ingesting and Manipulating Data with JavaScriptLucidworks
 
Scala4sling
Scala4slingScala4sling
Scala4slingday
 
Annotation processing and code gen
Annotation processing and code genAnnotation processing and code gen
Annotation processing and code genkoji lin
 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardMario Fusco
 
OrientDB introduction - NoSQL
OrientDB introduction - NoSQLOrientDB introduction - NoSQL
OrientDB introduction - NoSQLLuca Garulli
 

Ähnlich wie Power tools in Java (20)

Object Graph Mapping with Spring Data Neo4j 3 - Nicki Watt & Michael Hunger @...
Object Graph Mapping with Spring Data Neo4j 3 - Nicki Watt & Michael Hunger @...Object Graph Mapping with Spring Data Neo4j 3 - Nicki Watt & Michael Hunger @...
Object Graph Mapping with Spring Data Neo4j 3 - Nicki Watt & Michael Hunger @...
 
Metadata Extraction and Content Transformation
Metadata Extraction and Content TransformationMetadata Extraction and Content Transformation
Metadata Extraction and Content Transformation
 
Apache Beam de A à Z
 Apache Beam de A à Z Apache Beam de A à Z
Apache Beam de A à Z
 
Devoxx08 - Nuxeo Core, JCR 2, CMIS
Devoxx08 - Nuxeo Core, JCR 2, CMIS Devoxx08 - Nuxeo Core, JCR 2, CMIS
Devoxx08 - Nuxeo Core, JCR 2, CMIS
 
Creating A Language Editor Using Dltk
Creating A Language Editor Using DltkCreating A Language Editor Using Dltk
Creating A Language Editor Using Dltk
 
Global objects in Node.pdf
Global objects in Node.pdfGlobal objects in Node.pdf
Global objects in Node.pdf
 
Building Restful Web Services with Java
Building Restful Web Services with JavaBuilding Restful Web Services with Java
Building Restful Web Services with Java
 
GradleFX
GradleFXGradleFX
GradleFX
 
ApacheCon NA 2015 Spark / Solr Integration
ApacheCon NA 2015 Spark / Solr IntegrationApacheCon NA 2015 Spark / Solr Integration
ApacheCon NA 2015 Spark / Solr Integration
 
Dart structured web apps
Dart   structured web appsDart   structured web apps
Dart structured web apps
 
CouchDB-Lucene
CouchDB-LuceneCouchDB-Lucene
CouchDB-Lucene
 
Creating web applications with LODSPeaKr
Creating web applications with LODSPeaKrCreating web applications with LODSPeaKr
Creating web applications with LODSPeaKr
 
Introducing Node.js in an Oracle technology environment (including hands-on)
Introducing Node.js in an Oracle technology environment (including hands-on)Introducing Node.js in an Oracle technology environment (including hands-on)
Introducing Node.js in an Oracle technology environment (including hands-on)
 
Doctrine and NoSQL
Doctrine and NoSQLDoctrine and NoSQL
Doctrine and NoSQL
 
Jug java7
Jug java7Jug java7
Jug java7
 
Ingesting and Manipulating Data with JavaScript
Ingesting and Manipulating Data with JavaScriptIngesting and Manipulating Data with JavaScript
Ingesting and Manipulating Data with JavaScript
 
Scala4sling
Scala4slingScala4sling
Scala4sling
 
Annotation processing and code gen
Annotation processing and code genAnnotation processing and code gen
Annotation processing and code gen
 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forward
 
OrientDB introduction - NoSQL
OrientDB introduction - NoSQLOrientDB introduction - NoSQL
OrientDB introduction - NoSQL
 

Mehr von DPC Consulting Ltd

Mehr von DPC Consulting Ltd (7)

Scaling on AWS
Scaling on AWSScaling on AWS
Scaling on AWS
 
Jsonp coding dojo
Jsonp coding dojoJsonp coding dojo
Jsonp coding dojo
 
Garbage First Garbage Collector Algorithm
Garbage First Garbage Collector AlgorithmGarbage First Garbage Collector Algorithm
Garbage First Garbage Collector Algorithm
 
Két Java fejlesztő első Scala projektje
Két Java fejlesztő első Scala projektjeKét Java fejlesztő első Scala projektje
Két Java fejlesztő első Scala projektje
 
Server in your Client
Server in your ClientServer in your Client
Server in your Client
 
OSGi as Enterprise Integration Platform
OSGi as Enterprise Integration PlatformOSGi as Enterprise Integration Platform
OSGi as Enterprise Integration Platform
 
Full stack security
Full stack securityFull stack security
Full stack security
 

Kürzlich hochgeladen

SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 

Kürzlich hochgeladen (20)

SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 

Power tools in Java

  • 1. 1 Power Tools in Java SDK Elek Márton DPC Consulting Kft
  • 2. 2 • Modular static html site generator • (like Jekyll, github pages) • Do custom transformation on each text file • Example transformations: • ascii link break → <br/> • plain text → text with html header/footer <html>....<body>{...}</body></html> Example application
  • 3. 3 Code example – types public class Resource { private Map<String, String> headers = new HashMap<>(); private String content; … } public interface Transformer { public void transform(Resource resource); }
  • 4. 4 Code example – processing System.out.println("Transforming " + file); Resource r = new Resource(new String(Files.readAllBytes(file))); for (Transformer transformations : transformers) { transformations.transform(r); } return r;
  • 6. 6 • Kezdeti megoldás: private List<Transformer> transformations = new ArrayList(); public Generator() { transformations.add(new HtmlFrameTransformator()); transformations.add(new Nl2BrTransfomer()); } for (Transformer transformations : transformers) { transformations.transform(r); } • Cél • Dinamikusan kiterjeszthető • lib/-be új JAR → automatikusan elinduljon Modularitás
  • 7. 7 Step one: using descriptors • bin/ • site-generator.bat • site-generator.sh • lib/ • site-generator-1.0.jar • site-generator-extension-1.0.jar • config • transform-implementations.cfg: hu.dpc.javabar.powertools.impl.HtmlFrameTransformator hu.dpc.javabar.powertools.impl.Nl2BrTransfomer hu.dpc.javabar.powertools.impl.YoutubeTransformer
  • 8. 8 Step two: descriptor on classpath • bin/ • site-generator.bat, site-generator.sh • lib/ • site-generator-1.0.jar • site-generator-1.0.jar:/transform-implementations.cfg hu.dpc.javabar.powertools.impl.HtmlFrameTransformator hu.dpc.javabar.powertools.impl.Nl2BrTransfomer • site-generator-extension-1.0.jar • site-generator-extension-1.0.jar:/transform-implementations.cfg hu.dpc.javabar.powertools.impl.YoutubeTransformer Enumeration<URL> resources = getClass().getClassLoader().getResources("/transform-implementations.cfg");
  • 9. 9 Step three: Service Provider Interface • Standard, part of the JDK • Descriptor are on the classpath • Contains the class names of the implementations • Using nameconvention (META-INF/services/hu.dpc...Interface) • Simple API (ServiceLoader), only a few classes • Not included: • Dependency management • Versioning • Priority handling • Only answers the question: • Who implemented a specific interface
  • 10. 10 SPI code example • META-INF/services/hu.dpc.javabar.powertools.api.Transformer • hu.dpc.javabar.powertools.impl.HtmlFrameTransformer • hu.dpc.javabar.powertools.impl.Nl2BrTransfomer ServiceLoader<Transformer> transformers = ServiceLoader.load(Transformer.class); for (Transformer transfomer : transformers) { ... }
  • 11. 11 SPI – where is it used • (almost) everywhere • multiple location at JDK (eg. XML processor implementation) • Even the OSGi has adapter for SPI • Very effective even if it's very simple • Easy solution to avoid circular dependencies of the projects
  • 13. 13 How to generate SPI descriptors? • Service Provider Interface META-INF/services/... should be created and filled with implementation automatically
  • 14. 14 Annotation processors • Part of the javac from Java 6 • Run at compile time • Class/descriptor/... files could be generated based on specific annotated classes • Could be activated with SPI • META-INF/services/ javax.annotation.processing.Processor • Multiple iteration (processing the generated files) • Parameters could be used
  • 15. 15 Annotation processor public @interface Service { } @Service public class Nl2BrTransfomer implements Transformer { @Override public void transform(Resource resource) { resource.setContent( resource.getContent().replaceAll("nn", "<br/>") ); } }
  • 16. 16 Annotation processor example @SupportedAnnotationTypes("hu.dpc.javabar.powertools.Service") @SupportedSourceVersion(SourceVersion.RELEASE_7) public class ServiceAnnotationProcessor extends AbstractProcessor { Map<String, Set<String>> services = new HashMap<String, Set<String>>(); @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { … } }
  • 17. 17 Annotation processor example Map<String, Set<String>> services = new HashMap<String, Set<String>>(); @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "@service generation"); if (roundEnv.processingOver()) { writeOutServices(roundEnv); return false; } //process annotations ... }
  • 18. 18 Annotation processor example public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { //write out the file ... Elements elements = processingEnv.getElementUtils(); for (Element element : roundEnv.getElementsAnnotatedWith(Service.class)) { TypeElement type = (TypeElement) element; TypeElement contract = (TypeElement) ((DeclaredType) type.getInterfaces().get(0)).asElement(); String cn = elements.getBinaryName(contract).toString(); Set<String> v = services.get(cn); if (v == null) { services.put(cn, v = new TreeSet<String>()); } v.add(cn); } return false; }
  • 19. 19 Generating code for (Element element : roundEnv.getElementsAnnotatedWith(Service.class)) { TypeElement type = (TypeElement) element; JavaFileObject jfo = processingEnv.getFiler().createSourceFile( type.getQualifiedName() + "GeneratedInfo"); BufferedWriter bw = new BufferedWriter(jfo.openWriter()); bw.append("package "); bw.append(((PackageElement) type.getEnclosingElement()).getQualifiedName()); bw.append(";n"); bw.append("import hu.dpc.javabar.powertools.Service;n"); bw.newLine(); bw.newLine(); bw.append("@Service n"); bw.append(String.format("public class %s{", type.getSimpleName())); bw.newLine(); bw.append("public static final boolean PROCESSED = true;" ); bw.append("}"); bw.flush();
  • 20. 20 Project to generate SPI • To generate SPI descriptors, try • http://metainf-services.kohsuke.org/ • https://code.google.com/p/spi/ <dependency> <groupId>org.kohsuke.metainf-services</groupId> <artifactId>metainf-services</artifactId> <version>1.1</version> <optional>true</optional> </dependency>
  • 22. 22 Documentation of SPI implementation /** * Replace new double new lines with html line break. */ @Service("Replace new double new lines with html line break") public class Nl2BrTransfomer implements Transformer { @Override public void transform(Resource resource) { resource.setContent(resource.getContent().replaceAll("nn", "<br/>")); } } Available transformations: HtmlFrameTransformator : ... Nl2BrTransfomer : Replace new double new lines with html line break
  • 23. 23 How to access javadoc at runtime? >>> def hello(name): ... """Print hello for the name""" ... print("Hello", name) ... >>> hello("Bela") Hello Bela >>> print(hello.__doc__) Print hello for the name user=> (defn hello "Print hello for the name" [name] (str "Hello " name)) #'user/hello user=> (hello "Bela") "Hello Bela" user=> (get (meta (var hello)) :doc) "Print hello for the name" • The documentation of the annotated service class should come from javadoc documents • Easy with other languages(Python, Clojure)
  • 24. 24 Javadoc – Doclets • Formatting classes for custom javadoc generation • Doclet API could access all of the javadoc and class metadata information • Could be used to generate custom javadoc page but also to generate XML descriptors
  • 25. 25 Doclet example public class GenerateDocletResource { public static boolean start(RootDoc rootDoc) { for (ClassDoc cd : rootDoc.specifiedClasses()) { Path p = Paths.get(root + "/.../" + cd.qualifiedTypeName() + ".javadoc"); Files.createDirectories(p.getParent()); Files.write(p, cd.commentText().getBytes()); } return true; } }
  • 26. 26 Doclet loading public String getJavadoc(Class type) { String resourceName = "/" + type.getCanonicalName() + ".javadoc"; try (InputStream s = getClass().getResourceAsStream(resourceName)){ if (s == null) { return "Javadoc resource is missing for class " + type; } return new Scanner(s).useDelimiter("//Z").next(); } catch (IOException ex) { ... } }
  • 27. 27 Using it from Gradle dependencies { doclet project(":javadoc-metadata-generator") } task generateDocs(type: Javadoc) { source = sourceSets.main.allJava options = new SimpleJavadocOption() options.docletpath = configurations.doclet.files.asType(List) options.doclet = "hu.dpc.javabar.powertools.doc.GenerateDocletResource" } compileJava.dependsOn generateDocs
  • 28. 28 Using it from Maven <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <version>2.9.1</version> <executions> <execution> <id>doc-resource-generator</id> <phase>prepare-package</phase> <goals>javadoc</goals> </execution> </executions> <configuration> <doclet>org.umlgraph.doclet.UmlGraphDoc</doclet> <!-- <docletPath>/path/to/UmlGraph.jar</docletPath> --> <docletArtifact> <groupId>org.umlgraph</groupId> <artifactId>doclet</artifactId> <version>5.1</version> </docletArtifact> <additionalparam>-views</additionalparam> <useStandardDocletOptions>true</useStandardDocletOptions> </configuration> </plugin>
  • 30. 30 Java Management Extension (JMX) • Well known solution from the Standard Java API • Management • Monitoring • All of the JVM information could be accessed as well • Custom metrics could be added
  • 31. 31 JMX JSR • JSR 3: Java Management Extension (JMX) • JSR 160: JMX Remote API • JSR 255: JMX 2.0 = JSR 3 + 160 + … (Inactive) • JSR 262: Web Services Connector for JMX (Inactive) • Jolokia: REST interface adapter
  • 33. 33 JMX – Probe level • MBean – Managed Object: bármilyen resource • Attributes • Operations • Notifications • MBean types • Standard • Dynamic • MXBeans
  • 34. 34 Simple JMX example public interface GeneratorMBean { public void stop(); public int getProcessedFileNo(); } MBeanServer server = ManagementFactory.getPlatformMBeanServer(); ObjectName name = new ObjectName("hu.dpc.javabar.powertools", "name", "Generator"); server.registerMBean(generator, name); //generator implements GeneratorMBean
  • 36. 36 JMX platform Mbean server MBeanServer server = ManagementFactory.getPlatformMBeanServer();
  • 37. 37 JMX custom Mbean server MBeanServer server = MbeanServerFactory.createMBeanServer(); Registry registry = LocateRegistry.createRegistry(1234); JMXServiceURL jmxServiceURL = new JMXServiceURL("rmi", "localhost", 1235, "/jndi/rmi://localhost:1234/jmx"); JMXConnectorServer connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(jmxServiceURL, null, server); connectorServer.start(); System.out.println(jmxServiceURL); // service:jmx:rmi://localhost:1235/jndi/rmi://localhost:1234/jmx
  • 38. 38 JMX client API JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://localhost:1235/jndi/rmi://localhost:1234/jmx"); JMXConnector jmxc = JMXConnectorFactory.connect(url, null); MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(); ObjectName name = new ObjectName("hu.dpc.javabar.powertools", "name", "Generator"); GeneratorMBean mbean = JMX.newMBeanProxy(mbsc, name, GeneratorMBean.class); System.out.println(mbean.getProcessedFileNo()); //12
  • 40. 40 JMX custom MBeanServer MBeanServer server = MbeanServerFactory.createMBeanServer(); Registry registry = LocateRegistry.createRegistry(1234); JMXServiceURL jmxServiceURL = new JMXServiceURL("rmi", "localhost", 1235, "/jndi/rmi://localhost:1234/jmx"); JMXConnectorServer connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(jmxServiceURL, null, server); connectorServer.start(); System.out.println(jmxServiceURL); // service:jmx:rmi://localhost:1235/jndi/rmi://localhost:1234/jmx
  • 41. 41 JMX platform MBeanServer MBeanServer server = ManagementFactory.getPlatformMBeanServer();
  • 43. 43 Java Agents • Written in Java or C/C++ • Native: Java Virtual Machine Tool Interface (JVM TI) • -agentlib, -agentpath • Java: • -javaagent • Features • run custom command (in the application JVM-ben) • manipulating bytecode loading • Activating • Before application startup (-javaagent) • Attaching at runtime (Attach API)
  • 44. 44 Java Agent interface public static void premain(String agentArgs, Instrumentation inst) { } • Intstrumentation • addTransformer(ClassFileTransformer transformer) • Registers the supplied transformer. • appendToBootstrapClassLoaderSearch(JarFile jarfile) • Specifies a JAR file with instrumentation classes to be defined by the bootstrap class loader. • appendToSystemClassLoaderSearch(JarFile jarfile) • Specifies a JAR file with instrumentation classes to be defined by the system class loader • ClassFileTransformer. • transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer)
  • 45. 45 Activating Java Agent • Before application start • -javaagent:<jarpath>[=<options>] • META-INF/MANIFEST.MF: Premain-Class: … • public static void premain(...) • During application run • Attach API • META-INF/MANIFEST.MF: Agent-Class: … • public static void agentmain(...)
  • 46. 46 Attach API //JVMs of the CURRENT user List<VirtualMachineDescriptor> vms = VirtualMachine.list(); for (VirtualMachineDescriptor virtualMachineDescriptor : vms) { VirtualMachine vm = VirtualMachine.attach(virtualMachineDescriptor); if (vm != null) { System.out.println(virtualMachineDescriptor.displayName()); System.out.println("Java version = " + vm.getSystemProperties(). getProperty("java.version")); } }
  • 47. 47 JMX connection – with agents static final String CONNECTOR_ADDRESS = "com.sun.management.jmxremote.localConnectorAddress"; VirtualMachine vm = VirtualMachine.attach(id); String connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS); if (connectorAddress == null) { String agent = vm.getSystemProperties().getProperty("java.home") + File.separator + "lib" + File.separator + "management-agent.jar"; vm.loadAgent(agent); connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS); } JMXServiceURL url = new JMXServiceURL(connectorAddress); JMXConnector = JMXConnectorFactory.connect(url);
  • 48. 48 Where is it used? • Bytecode manipulation • AspectJ • Spring • Persistence frameworks • BTrace • premain/agent: • jre/lib/management-agent.jar
  • 49. 49 Summary • JDK Power tools • Service Provider Interface – for modularity • Annotation processors – compile time processing • Javadoc doclet – Javadoc (pre)processing • JMX – runtime metrics, methods • Agentek, Attach API – byte code manipulation, runtime modification
  • 50. 50 Credits • Thanks for the image authors: • Container, Sandor Volenszki, Creative Commons • Blueprint, Will Scullin, Creative Commons • Robot, Avram Cheaney, Creative Commons • Control Panel, Paul, Creative Commons • PCB, Karl-Ludwig G. Poggemann, Creative Commons
  • 51. 51 Elek Márton / DPC Consulting marton.elek@dpc.hu http://www.meetup.com/bpjavabar/