In this talk I'll explore different techniques in and around Java that extend or complement the existing language features at compile or runtime.
Examples are Source and Byte Code generation, Annotation Processing and compile-time defect analysis. The talk is not specific to any Java version. Code sample will use Java 8, but could be easily adapted to previous versions (1.6+).
As the talk is called "Hacking Java", the focus will not only be on established best practices, but also on techniques of a more experimental nature. The talk is accompanied by a GitHub project with code samples and unit tests for every single technique.
Talk from JVMLS2014 on Nashorn moving towards a generic execution architecture for dynamic languages on the JVM. Explains the optimistic type architecture that is the basis for this. Also covers the last year's large leaps in performance.
Talk from JVMLS2014 on Nashorn moving towards a generic execution architecture for dynamic languages on the JVM. Explains the optimistic type architecture that is the basis for this. Also covers the last year's large leaps in performance.
Григорий Шехет "Treasure hunt in the land of Reactive frameworks"Fwdays
Мне нравится использовать React. Данная библиотека – отличное решение для многих задач, так как она не навязывает конкретный паттерн или архитектуру. Разработчик сам решает что лучше для той или иной ситуации.
Существует множество уже готовых архитектурных решений. Большинство выбирает Redux. Существует множество библиотек использующее идеи FRP, например Calmm или MobX. Как результат, получаем много подходов, решающие одну и туже задачу.
В своем докладе хочу поговорить о различных архитектурных решениях, посмотреть на плюсы и минусы той или иной библиотеки, и прийти к консенсусу.
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...Codemotion
Scala is the only language that can be used to produce code that can be "trans/compiled" for the JVM, in Javascript and in native binary. This allows to write libraries that are usable in JVM and JS using the power of functional programming (i.e. cats, scalaz), generic programming (i.e. shapeless) and macro/scalameta available in Scala. In this talk, we will see how to write a Scala application backend and a SPA (scala.js/scala-js-react) that share the same code as a business logic, datamodels and transparent API call (JVM/JS) in Scala (via autowire/akka-http/circe).
First Name: Stephane
Last Name: Ducasse
Video: https://youtu.be/OGkGgx4iymM
Title: A Taste for Pharo 70
In this talk I will present the roadmap for Pharo 70.
- support for Undefined Classes
- Class Parser
- new class definition
- support for namespace (not namespace) modules.
- ...
Bio:
Stéphane is directeur de recherche at Inria. He leads the RMoD
(http://rmod.lille.inria.fr) team. He is expert in two domains:
object-oriented language design and reengineering. He worked on
traits, composable groups of methods. Traits have been introduced in Pharo, Perl, PHP and under a variant into Scala and Fortress. He is also expert on software quality, program understanding, program
visualisations, reengineering and metamodeling. He is one of the
developer of Moose, an open-source software analysis platform
http://www.moosetechnology.org/. He created http://www.synectique.eu/
a company building dedicated tools for advanced software analyses. He
is one of the leader of Pharo (http://www.pharo.org/) a dynamic
reflective object-oriented language supporting live programming. The
objective of Pharo is to create an ecosystem where innovation and
business bloom. He wrote several books such as Functional Programming
in Scheme, Pharo by Example, Deep into Pharo, Object-oriented
Reengineering Patterns, Dynamic web development with Seaside.
According to google his h-index is 51 for more than 11000
citations. He would like to thanks all the researchers making
reference to his work!
(COSCUP 2015) A Beginner's Journey to Mozilla SpiderMonkey JS EngineZongXian Shen
This is my slides of COSCUP 2015 at Taipei, Taiwan.
The material is about the engine implementation overview from a 3 month experienced mentor bug contributor.
Talk given at Lua Workshop 2016 - San Francisco.
Building a solid bridge between Lua and an entire OS SDK is certainly a complex and challenging task. You need to adapt the calling conventions and design patterns used in the OS SDK to make them feel simple and natural in Lua; you have to manage the peaceful coexistence of different memory management models, and of different typing systems; and of course you have to write the binding code that allow Lua code and the native OS SDK to communicate with each other. In this talk, I explain how these points were handled in the Lua to iOS / macOS bridge we have developed as part of the CodeFlow IDE, and how integrating the bridge with the IDE can greatly improve the developer experience.
CodeFlow is a software development system that makes possible the truly-interactive development in Lua of iOS and OS X Apps.
This presentation highlights the most important IDE features of CodeFlow: syntax-driven editor, advanced debugger, Lua modules manager and automatic bindings generator.
How the HotSpot and Graal JVMs execute Java CodeJim Gough
When Java was released in 1995 it was slow, a reputation it has carried for many years… Today Java can give performance that is comparable to C++ and can emit instructions that are more optimal than code which is statically compiled. But how?
This talk will explore practical examples and the subsystems that are involved in interpreting, compiling and executing a simple Hello World Application. We will dive into JIT compilation and the arrival of the JVM Compiler Interface (JVMCI) to explore how optimisations are applied to boost the performance of our application. We will discuss HotSpot, explore Graal and the JVM ecosystem to discover performance benefits of a platform 25 years in the making.
Making Java more dynamic: runtime code generation for the JVMRafael Winterhalter
While Java’s strict type system is a great help for avoiding programming errors, it also takes away some of the flexibility that developers appreciate when using dynamic languages. By using runtime code generation, it is possible to bring some of this flexibility back to the Java virtual machine. For this reason, runtime code generation is widely used by many state-of-the-art Java frameworks for implementing POJO-centric APIs but it also opens the door to assembling more modular applications. This presentation offers an introduction to the complex of runtime code generation and its use on the Java platform. Furthermore, it discusses the up- and downsides of several code generation libraries such as ASM, Javassist, cglib and Byte Buddy.
Григорий Шехет "Treasure hunt in the land of Reactive frameworks"Fwdays
Мне нравится использовать React. Данная библиотека – отличное решение для многих задач, так как она не навязывает конкретный паттерн или архитектуру. Разработчик сам решает что лучше для той или иной ситуации.
Существует множество уже готовых архитектурных решений. Большинство выбирает Redux. Существует множество библиотек использующее идеи FRP, например Calmm или MobX. Как результат, получаем много подходов, решающие одну и туже задачу.
В своем докладе хочу поговорить о различных архитектурных решениях, посмотреть на плюсы и минусы той или иной библиотеки, и прийти к консенсусу.
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...Codemotion
Scala is the only language that can be used to produce code that can be "trans/compiled" for the JVM, in Javascript and in native binary. This allows to write libraries that are usable in JVM and JS using the power of functional programming (i.e. cats, scalaz), generic programming (i.e. shapeless) and macro/scalameta available in Scala. In this talk, we will see how to write a Scala application backend and a SPA (scala.js/scala-js-react) that share the same code as a business logic, datamodels and transparent API call (JVM/JS) in Scala (via autowire/akka-http/circe).
First Name: Stephane
Last Name: Ducasse
Video: https://youtu.be/OGkGgx4iymM
Title: A Taste for Pharo 70
In this talk I will present the roadmap for Pharo 70.
- support for Undefined Classes
- Class Parser
- new class definition
- support for namespace (not namespace) modules.
- ...
Bio:
Stéphane is directeur de recherche at Inria. He leads the RMoD
(http://rmod.lille.inria.fr) team. He is expert in two domains:
object-oriented language design and reengineering. He worked on
traits, composable groups of methods. Traits have been introduced in Pharo, Perl, PHP and under a variant into Scala and Fortress. He is also expert on software quality, program understanding, program
visualisations, reengineering and metamodeling. He is one of the
developer of Moose, an open-source software analysis platform
http://www.moosetechnology.org/. He created http://www.synectique.eu/
a company building dedicated tools for advanced software analyses. He
is one of the leader of Pharo (http://www.pharo.org/) a dynamic
reflective object-oriented language supporting live programming. The
objective of Pharo is to create an ecosystem where innovation and
business bloom. He wrote several books such as Functional Programming
in Scheme, Pharo by Example, Deep into Pharo, Object-oriented
Reengineering Patterns, Dynamic web development with Seaside.
According to google his h-index is 51 for more than 11000
citations. He would like to thanks all the researchers making
reference to his work!
(COSCUP 2015) A Beginner's Journey to Mozilla SpiderMonkey JS EngineZongXian Shen
This is my slides of COSCUP 2015 at Taipei, Taiwan.
The material is about the engine implementation overview from a 3 month experienced mentor bug contributor.
Talk given at Lua Workshop 2016 - San Francisco.
Building a solid bridge between Lua and an entire OS SDK is certainly a complex and challenging task. You need to adapt the calling conventions and design patterns used in the OS SDK to make them feel simple and natural in Lua; you have to manage the peaceful coexistence of different memory management models, and of different typing systems; and of course you have to write the binding code that allow Lua code and the native OS SDK to communicate with each other. In this talk, I explain how these points were handled in the Lua to iOS / macOS bridge we have developed as part of the CodeFlow IDE, and how integrating the bridge with the IDE can greatly improve the developer experience.
CodeFlow is a software development system that makes possible the truly-interactive development in Lua of iOS and OS X Apps.
This presentation highlights the most important IDE features of CodeFlow: syntax-driven editor, advanced debugger, Lua modules manager and automatic bindings generator.
How the HotSpot and Graal JVMs execute Java CodeJim Gough
When Java was released in 1995 it was slow, a reputation it has carried for many years… Today Java can give performance that is comparable to C++ and can emit instructions that are more optimal than code which is statically compiled. But how?
This talk will explore practical examples and the subsystems that are involved in interpreting, compiling and executing a simple Hello World Application. We will dive into JIT compilation and the arrival of the JVM Compiler Interface (JVMCI) to explore how optimisations are applied to boost the performance of our application. We will discuss HotSpot, explore Graal and the JVM ecosystem to discover performance benefits of a platform 25 years in the making.
Making Java more dynamic: runtime code generation for the JVMRafael Winterhalter
While Java’s strict type system is a great help for avoiding programming errors, it also takes away some of the flexibility that developers appreciate when using dynamic languages. By using runtime code generation, it is possible to bring some of this flexibility back to the Java virtual machine. For this reason, runtime code generation is widely used by many state-of-the-art Java frameworks for implementing POJO-centric APIs but it also opens the door to assembling more modular applications. This presentation offers an introduction to the complex of runtime code generation and its use on the Java platform. Furthermore, it discusses the up- and downsides of several code generation libraries such as ASM, Javassist, cglib and Byte Buddy.
BarcelonaJUG2016: walkmod: how to run and design code transformationswalkmod
walkmod is an open source tool to apply and share code conventions. Code conventions are internally designed as code transformations. In this sessions we will se how to run walkmod in a real project and how to contribute designing automatic quick fixes for existing PMD, Checkstyle or Sonar rules
Java 8 introduces new type annotation syntax (JSR 308) permitting annotations to appear on any use of a type. Type annotations provide exciting new opportunities for tooling such as detecting additional classes of errors at compile-time. This presentation provides an overview of the new type annotation syntax, tools for leveraging type annotations, and type annotation design patterns.
These slides are from Todd Schiller's talk at the March 24th New York City Java Meetup.
A presentation at Twitter's official developer conference, Chirp, about why we use the Scala programming language and how we build services in it. Provides a tour of a number of libraries and tools, both developed at Twitter and otherwise.
Rapid Web API development with Kotlin and KtorTrayan Iliev
Introduction to Kotlin and Ktor with flow, async and channel examples. Ktor is an async web framework with minimal ceremony that leverages the advantages of Kotlin like coroutines and extensible functional DSLs..
Video at https://www.youtube.com/watch?v=nD1eFbql8jg
This talk will demonstrate advanced testing practices used by the XWiki open source project, and using Java, Maven, Docker and Jenkins:
* Testing for backward compatibility with Revapi and an associated strategy
* Testing for coverage with Jacoco and defining a viable strategy for slowing improving the situation
* Testing the quality of your tests with Descartes Mutation testing
Automatically enriching your test suite with DSpot
* Testing various configurations with Docker containers and Jenkins
Abstract 2: "Advanced testing in action on a Java project"
In 2019 we're all used to writing automated tests in Java projects. It's now time to move up the chain and learn how to implement more complex type of testing.
This talk will demonstrate advanced testing practices used by the XWiki open source project (http://xwiki.org), and using Java, Maven, Docker and Jenkins and more:
* Testing for backward compatibility with Revapi and an associated strategy
* Testing for coverage with Jacoco and defining a viable strategy for slowing improving the situation
* Testing the quality of your tests with Descartes Mutation testing
* Automatically enriching your test suite with DSpot
* Testing various configurations with Docker containers and Jenkins
This talk demonstrates advanced testing practices coming from the STAMP research project and applied to the XWiki open source project:
- Testing for coverage with Jacoco and defining a viable strategy for slowly improving the situation
- Testing the quality of your tests with Descartes Mutation testing
- Automatically enriching your test suite with DSpot
- Testing various configurations with Docker containers and Jenkins
- Generating tests automatically from production stack traces
SE2016 - Java EE revisits design patterns 2016Alex Theedom
Design patterns are not only cool but represent the collective wisdom of many developers. Since the publication of Design Patterns: Elements of Reusable Object-Oriented Software by GoF many new concepts have extended the coverage of these design patterns, and now Java EE provides out-of-the box implementations of many of the most well known patterns. This talk will show how, by taking advantage of Java EE features such as CDI and the smart use of annotations, traditional design patterns can be implemented in a much cleaner and quicker way. Among the design patterns discuss there will be Singleton, Façade, Observer, Factory, Dependency Injection, Decorator and more.
Design patterns are not only cool but represent the collective wisdom of many developers. Since the publication of Design Patterns: Elements of Reusable Object-Oriented Software by GoF many new concepts have extended the coverage of these design patterns, and now Java EE provide out of the box implementations of many of the most well known patterns. This talk will show how, by taking advantage of Java EE features such as CDI and the smart use of annotations, traditional design patterns can be implemented in a much cleaner and quicker way. Among the design patterns discuss there will be Singleton, Façade, Observer, Factory, Dependency Injection, Decorator and more.
Design patterns are not only cool but represent the collective wisdom of many developers. Since the publication of Design Patterns: Elements of Reusable Object-Oriented Software by GoF many new concepts have extended the coverage of these design patterns, and now Java EE provide out of the box implementations of many of the most well known patterns. This talk will show how, by taking advantage of Java EE features such as CDI and the smart use of annotations, traditional design patterns can be implemented in a much cleaner and quicker way. Among the design patterns discuss there will be Singleton, Façade, Observer, Factory, Dependency Injection, Decorator and more.
Игорь Фесенко "Direction of C# as a High-Performance Language"Fwdays
There are a lot of upcoming performance changes in .NET. Starting from code generation (JIT, AOT) and optimizations that can be performed by the compiler (inlining, flowgraph & loop analysis, dead code elimination, SIMD, stack allocation and so on). In this talk we will cover some features of C# 7 are going towards making low level optimization.
I will share not only how we can improve performance with the next version of .NET, but how we can do it today using different techniques and tools like Roslyn analyzers, Channels (Push based Streams), System.Slices, System.Buffers and System.Runtime.CompilerServices.Unsafe.
"WTF is Twisted? (or; owl amongst the ponies)" is a talk that introduces the Twisted asynchronous programming framework, how it works, and what uses it.
Mock what? What Mock?Learn What is Mocking, and how to use Mocking with ColdFusion testing, development, and continuous integration. Look at Mocking and Stubbing with a touch of Theory and a lot of Examples, including what you could test, and what you should test… and what you shouldn't test (but might be fun).
These slides would share our experiences in reusing the legacy automation testing code (Selenium+xpath) in IE. To reuse our legacy code in IE, we explored three techinques, i.e., CSS selectors, jQuery selectors, Javascript-xpath library.
These slides would discuss each technique and explain how we addressed the limitations of existing teachniques. The discussions would present how to rejuvenate the legacy code at code level and library level. Finally, the best practices would be summarized based on the practical experiences.
Patrick Chanezon and Guillaume Laforge are presenting Google App Engine Java and Gaelyk, the lightweight groovy toolkit on top of the GAE SDK, at the Devoxx conference
Design patterns are not only cool but represent the collective wisdom of many developers. Since the publication of Design Patterns: Elements of Reusable Object-Oriented Software by GoF many new concepts have extended the coverage of these design patterns, and now Java EE provides out-of-the box implementations of many of the most well known patterns. This talk will show how, by taking advantage of Java EE features such as CDI and the smart use of annotations, traditional design patterns can be implemented in a much cleaner and quicker way. Among the design patterns discuss there will be Singleton, Façade, Observer, Factory, Dependency Injection, Decorator and more.
Genomic Computation at Scale with Serverless, StackStorm and Docker SwarmDmitri Zimine
Presented on SuperComputing SC17 on Nov 14/2017 by Dmitri Zimine.
This talk is a story of bio-tech meeting DevOps to produce genomic computations, economically, and at scale.
Genomic computation is growing in demand as it comes to the mainstream practices of bio-technology, agriculture, and personal medicine. It also explodes the demand for compute resources. In fact, with inexpensive next-gen sequencing, some labs sequence over 1,000,000 billion bases per year. Genetic data banks are growing over 10x annually. How to compute the genomic data at massive scale, and do it in a cost-efficient way?
In the presentation, we describe and demonstrate a serverless solution built with Docker, Docker Swarm, StackStorm and other tools from the DevOps toolchain on AWS. The solution offers a new take on creating and computing a bio-informatic pipelines that can run at high scale and at optimal cost.
http://sc17.supercomputing.org/presentation/?id=exforum106&sess=sess150
Similar to Hacking Java - Enhancing Java Code at Build or Runtime (20)
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdfJay Das
With the advent of artificial intelligence or AI tools, project management processes are undergoing a transformative shift. By using tools like ChatGPT, and Bard organizations can empower their leaders and managers to plan, execute, and monitor projects more effectively.
How Recreation Management Software Can Streamline Your Operations.pptxwottaspaceseo
Recreation management software streamlines operations by automating key tasks such as scheduling, registration, and payment processing, reducing manual workload and errors. It provides centralized management of facilities, classes, and events, ensuring efficient resource allocation and facility usage. The software offers user-friendly online portals for easy access to bookings and program information, enhancing customer experience. Real-time reporting and data analytics deliver insights into attendance and preferences, aiding in strategic decision-making. Additionally, effective communication tools keep participants and staff informed with timely updates. Overall, recreation management software enhances efficiency, improves service delivery, and boosts customer satisfaction.
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns
Unlocking Business Potential: Tailored Technology Solutions by Prosigns
Discover how Prosigns, a leading technology solutions provider, partners with businesses to drive innovation and success. Our presentation showcases our comprehensive range of services, including custom software development, web and mobile app development, AI & ML solutions, blockchain integration, DevOps services, and Microsoft Dynamics 365 support.
Custom Software Development: Prosigns specializes in creating bespoke software solutions that cater to your unique business needs. Our team of experts works closely with you to understand your requirements and deliver tailor-made software that enhances efficiency and drives growth.
Web and Mobile App Development: From responsive websites to intuitive mobile applications, Prosigns develops cutting-edge solutions that engage users and deliver seamless experiences across devices.
AI & ML Solutions: Harnessing the power of Artificial Intelligence and Machine Learning, Prosigns provides smart solutions that automate processes, provide valuable insights, and drive informed decision-making.
Blockchain Integration: Prosigns offers comprehensive blockchain solutions, including development, integration, and consulting services, enabling businesses to leverage blockchain technology for enhanced security, transparency, and efficiency.
DevOps Services: Prosigns' DevOps services streamline development and operations processes, ensuring faster and more reliable software delivery through automation and continuous integration.
Microsoft Dynamics 365 Support: Prosigns provides comprehensive support and maintenance services for Microsoft Dynamics 365, ensuring your system is always up-to-date, secure, and running smoothly.
Learn how our collaborative approach and dedication to excellence help businesses achieve their goals and stay ahead in today's digital landscape. From concept to deployment, Prosigns is your trusted partner for transforming ideas into reality and unlocking the full potential of your business.
Join us on a journey of innovation and growth. Let's partner for success with Prosigns.
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Globus
The Earth System Grid Federation (ESGF) is a global network of data servers that archives and distributes the planet’s largest collection of Earth system model output for thousands of climate and environmental scientists worldwide. Many of these petabyte-scale data archives are located in proximity to large high-performance computing (HPC) or cloud computing resources, but the primary workflow for data users consists of transferring data, and applying computations on a different system. As a part of the ESGF 2.0 US project (funded by the United States Department of Energy Office of Science), we developed pre-defined data workflows, which can be run on-demand, capable of applying many data reduction and data analysis to the large ESGF data archives, transferring only the resultant analysis (ex. visualizations, smaller data files). In this talk, we will showcase a few of these workflows, highlighting how Globus Flows can be used for petabyte-scale climate analysis.
Unleash Unlimited Potential with One-Time Purchase
BoxLang is more than just a language; it's a community. By choosing a Visionary License, you're not just investing in your success, you're actively contributing to the ongoing development and support of BoxLang.
Enterprise Resource Planning System includes various modules that reduce any business's workload. Additionally, it organizes the workflows, which drives towards enhancing productivity. Here are a detailed explanation of the ERP modules. Going through the points will help you understand how the software is changing the work dynamics.
To know more details here: https://blogs.nyggs.com/nyggs/enterprise-resource-planning-erp-system-modules/
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteGoogle
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
👉👉 Click Here To Get More Info 👇👇
https://sumonreview.com/ai-pilot-review/
AI Pilot Review: Key Features
✅Deploy AI expert bots in Any Niche With Just A Click
✅With one keyword, generate complete funnels, websites, landing pages, and more.
✅More than 85 AI features are included in the AI pilot.
✅No setup or configuration; use your voice (like Siri) to do whatever you want.
✅You Can Use AI Pilot To Create your version of AI Pilot And Charge People For It…
✅ZERO Manual Work With AI Pilot. Never write, Design, Or Code Again.
✅ZERO Limits On Features Or Usages
✅Use Our AI-powered Traffic To Get Hundreds Of Customers
✅No Complicated Setup: Get Up And Running In 2 Minutes
✅99.99% Up-Time Guaranteed
✅30 Days Money-Back Guarantee
✅ZERO Upfront Cost
See My Other Reviews Article:
(1) TubeTrivia AI Review: https://sumonreview.com/tubetrivia-ai-review
(2) SocioWave Review: https://sumonreview.com/sociowave-review
(3) AI Partner & Profit Review: https://sumonreview.com/ai-partner-profit-review
(4) AI Ebook Suite Review: https://sumonreview.com/ai-ebook-suite-review
Quarkus Hidden and Forbidden ExtensionsMax Andersen
Quarkus has a vast extension ecosystem and is known for its subsonic and subatomic feature set. Some of these features are not as well known, and some extensions are less talked about, but that does not make them less interesting - quite the opposite.
Come join this talk to see some tips and tricks for using Quarkus and some of the lesser known features, extensions and development techniques.
May Marketo Masterclass, London MUG May 22 2024.pdfAdele Miller
Can't make Adobe Summit in Vegas? No sweat because the EMEA Marketo Engage Champions are coming to London to share their Summit sessions, insights and more!
This is a MUG with a twist you don't want to miss.
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...Juraj Vysvader
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I didn't get rich from it but it did have 63K downloads (powered possible tens of thousands of websites).
A Comprehensive Look at Generative AI in Retail App Testing.pdfkalichargn70th171
Traditional software testing methods are being challenged in retail, where customer expectations and technological advancements continually shape the landscape. Enter generative AI—a transformative subset of artificial intelligence technologies poised to revolutionize software testing.
Into the Box Keynote Day 2: Unveiling amazing updates and announcements for modern CFML developers! Get ready for exciting releases and updates on Ortus tools and products. Stay tuned for cutting-edge innovations designed to boost your productivity.
Software Engineering, Software Consulting, Tech Lead.
Spring Boot, Spring Cloud, Spring Core, Spring JDBC, Spring Security,
Spring Transaction, Spring MVC,
Log4j, REST/SOAP WEB-SERVICES.
Code reviews are vital for ensuring good code quality. They serve as one of our last lines of defense against bugs and subpar code reaching production.
Yet, they often turn into annoying tasks riddled with frustration, hostility, unclear feedback and lack of standards. How can we improve this crucial process?
In this session we will cover:
- The Art of Effective Code Reviews
- Streamlining the Review Process
- Elevating Reviews with Automated Tools
By the end of this presentation, you'll have the knowledge on how to organize and improve your code review proces
Enhancing Research Orchestration Capabilities at ORNL.pdfGlobus
Cross-facility research orchestration comes with ever-changing constraints regarding the availability and suitability of various compute and data resources. In short, a flexible data and processing fabric is needed to enable the dynamic redirection of data and compute tasks throughout the lifecycle of an experiment. In this talk, we illustrate how we easily leveraged Globus services to instrument the ACE research testbed at the Oak Ridge Leadership Computing Facility with flexible data and task orchestration capabilities.
Experience our free, in-depth three-part Tendenci Platform Corporate Membership Management workshop series! In Session 1 on May 14th, 2024, we began with an Introduction and Setup, mastering the configuration of your Corporate Membership Module settings to establish membership types, applications, and more. Then, on May 16th, 2024, in Session 2, we focused on binding individual members to a Corporate Membership and Corporate Reps, teaching you how to add individual members and assign Corporate Representatives to manage dues, renewals, and associated members. Finally, on May 28th, 2024, in Session 3, we covered questions and concerns, addressing any queries or issues you may have.
For more Tendenci AMS events, check out www.tendenci.com/events
4. @oldJavaGuy#VoxxedBerlin
Scope of this talk
• Overview of non-standard techniques
• Grouped by use case
• Some techniques are more mature than others
• Code samples and unit tests
7. @oldJavaGuy#VoxxedBerlin
Use Case: Value Objects
• Standard, well defined behavior
(equals(), hashCode(),
toString()) according to
Effective Java
• Mutable or immutable, with
constructors, factory methods
or builders
• Java Boilerplate very verbose
and error-prone
8. @oldJavaGuy#VoxxedBerlin
The Pain
public class MyValueObject {
private final String property1; private final boolean property2;
public MyValueObject(String property1, boolean property2) {
this.property1 = property1; this.property2 = property2;
}
public String getProperty1() { return property1; }
public boolean isProperty2() { return property2; }
@Override public int hashCode() { return Objects.hash(property1, property2); }
@Override public boolean equals(Object obj) {
if (this == obj) { return true; }
else if (obj instanceof MyValueObject) {
MyValueObject other = (MyValueObject) obj;
return Objects.equals(this.property1, other.property1)
&& Objects.equals(this.property2, other.property2);
} else { return false; } }
@Override public String toString() {
return MoreObjects.toStringHelper(this).add("property1", property1).add("property2", property2).toString();
}
}
10. @oldJavaGuy#VoxxedBerlin
For comparison: Scala
case class MyValueObject(property1: String, property2: Boolean) {}
Source: http://onlyinamericablogging.blogspot.com/2014/11/move-along-now-nothing-to-see-here.html
11. @oldJavaGuy#VoxxedBerlin
Boilerplate
• equals() / hashCode() / toString() /
getters / setters / constructors /
compareTo()
• IDEs offer generation, but in a static way
• potential bugs: adding or removing fields
• Boilerplate (n.): newspaper [and IT]
slang for "unit of writing that can be
used over and over without change,"
1893, from a literal meaning (1840)
"metal rolled in large, flat plates for use
in making steam boilers."
Source: http://www.etymonline.com/ https://en.wikipedia.org/wiki/Boilerplate_(robot)
12. @oldJavaGuy#VoxxedBerlin
Plan
• Let’s look at technologies that let us define value objects in a
less-verbose way
• But with the full functionality (a test suite will monitor
correct working of getters, equals, hashCode and toString)
• Different approaches: build-time, compile-time, run-time
13. @oldJavaGuy#VoxxedBerlin
Testing
• Expected Data structure (mutable or immutable):
User
- firstName (String)
- lastName (String)
- birthDate (LocalDate)
- addresses (List[Address])
Address
- street (String)
- zipCode (int)
- city (String)
14. @oldJavaGuy#VoxxedBerlin
Test suite for value objects
public abstract class BaseUserTest {
protected static final String FIRST_NAME = "Fred"; // etc.
@Test public void equalsAndHashCodeAreSymmetrical() {
Object user1 = createUser(); Object user2 = createUser();
assertThat(user1, is(equalTo(user2))); assertThat(user2, is(equalTo(user1)));
assertThat(user1.hashCode(), is(equalTo(user2.hashCode()))); }
@Test public void toStringIsConsistent() {
assertThat(createUser().toString(), is(equalTo(createUser().toString())));
String s = createUser().toString();
assertThat(s, containsString(FIRST_NAME)); /* etc. */ }
@SuppressWarnings({"unchecked", "rawtypes"}) @Test public void compareToIsSymmetrical() {
Object l = createUser(), r = createUser();
assertThat(l, instanceOf(Comparable.class));
assertThat(r, instanceOf(Comparable.class));
assertThat(((Comparable) l).compareTo(r), equalTo(((Comparable) r).compareTo(l))); }
}
15. @oldJavaGuy#VoxxedBerlin
Test suite (continued)
@Test public void propertyMapHasCorrectValues() {
Object instance = createUser();
Map<String, Object> map = getPropertyMap(instance);
assertThat(map, hasEntry("firstName", FIRST_NAME)); // etc.
}
private static Map<String, Object> getPropertyMap(Object instance) {
final Map<String, Object> map = new TreeMap<>();
try { Arrays.stream(Introspector.getBeanInfo(instance.getClass(), Object.class)
.getPropertyDescriptors()).filter((it) -> it.getReadMethod() != null)
.forEach((pD) -> { Method m = propertyDescriptor.getReadMethod();
try { Object o = m.invoke(instance); map.put(pD.getName(), o);
} catch (IllegalAccessException | ... e) { throw new ISE(e); }});
} catch (IntrospectionException e) { throw new IllegalStateException(e); }
return propertyMap;
}
protected abstract Object createUser();
16. @oldJavaGuy#VoxxedBerlin
Alternative Test Suite
• Guava’s AbstractPackageSanityTests
( http://bit.ly/AbstractPackageSanityTests )
• Automatically runs sanity checks against top level classes in
the same package of the test that extends
AbstractPackageSanityTests. Currently sanity checks include
NullPointerTester, EqualsTester and SerializableTester.
• Nice, but not a perfect match for this use case
17. @oldJavaGuy#VoxxedBerlin
Annotation Processing
• JSR 269, pluggable annotation processing:
Separate compiler lifecycle, well suited for code generation
• Service auto-discovery through ServiceLoader:
/META-INF/services/javax.annotation.processing.Processor
contains qualified processor names ( http://bit.ly/srvcLdr )
• Docs: http://bit.ly/annotationProcessing (Oracle JavaDocs)
18. @oldJavaGuy#VoxxedBerlin
Project Lombok
• Name: Lombok is an Indonesian Island
neighboring Java (“it’s not quite Java, but
almost”)
• Project Lombok uses Annotation Processing
to extend the AST. It uses internal compiler
APIs (Javac and Eclipse)
• Advantages: Little code, lots of power, no
runtime dependencies
• Disadvantages: Relying on undocumented
internal APIs, adds code that is not reflected
in sources (inconsistent)
Source: http://bit.ly/1lOfPbC
19. @oldJavaGuy#VoxxedBerlin
Lombok: mutable example
@Data
public class MyValueObject {
private String property1;
private boolean property2;
}
• Generates getters, setters, equals, hashCode, toString
• Additional fine-tuning annotations are available
21. @oldJavaGuy#VoxxedBerlin
Google AutoValue
• https://github.com/google/auto/tree/master/value
• “AutoValue […] is actually a great tool for eliminating the
drudgery of writing mundane value classes in Java. It
encapsulates much of the advice in Effective Java […].The
resulting program is likely to be shorter, clearer, and freer of
bugs.” -- Joshua Bloch, author, Effective Java
• Advantages: Only public APIs used, no runtime dependencies
• Disadvantages: Less power and flexibility, only immutable
types supported (or is that an advantage?)
22. @oldJavaGuy#VoxxedBerlin
AutoValue Sample code
@AutoValue // class needs to be abstract
public abstract class MyValueObject {
// use JavaBeans property names or simple field names
public abstract String getProperty1();
public abstract boolean isProperty2();
// factory method for instantiation
static MyValueObject create(String p1, boolean p2){
return new AutoValue_MyValueObject(p1, p2);
//"AutoValue_" + abstract class name
}
}
23. @oldJavaGuy#VoxxedBerlin
CGLib BeanGenerator
• https://github.com/cglib/cglib
• CGLib is a “high level” byte code manipulation framework
• Widely used in production code, mostly by IOC and ORM
frameworks (Spring, Guice etc)
• BeanGenerator is a playground feature that can create value
types on the fly
• Works on Byte Code:
https://en.wikipedia.org/wiki/Java_bytecode
24. @oldJavaGuy#VoxxedBerlin
Caveat
• BeanGenerator generates field + getter + setter (no immutable types,
no equals(), hashCode(), toString())
• To solve these issues, I am creating a dynamic proxy around the
generated class, which in turn uses a full JavaBeans property map for all
operations.
• /* This is O(scary), but seems quick enough in practice. */
( Source: http://bit.ly/bigOScary )
• There is probably no sane use case for this
25. @oldJavaGuy#VoxxedBerlin
Generating types on the fly
public static Class<?> createBeanClass(
final String className, // qualified type
Map<String, Class<?>> props) {
BeanGenerator beanGenerator = new BeanGenerator();
/* use our own hard coded class name */
beanGenerator.setNamingPolicy(new NamingPolicy() {
@Override public String getClassName(...) {
return className; }});
BeanGenerator.addProperties(beanGenerator, props);
return (Class<?>) beanGenerator.createClass();
}
29. @oldJavaGuy#VoxxedBerlin
Don’t try this at home!
• There is (almost) no sane
reason for generating value
classes at runtime
• One possible scenario would
be a CMS that lets you add new
content types at runtime and is
backed by a class-based ORM
Source: http://www.richardbealblog.com/dont-try-this-at-home/
32. @oldJavaGuy#VoxxedBerlin
Code Generation
• Techniques for creating source code dynamically at build time
before compiling
• For those of us who like to “write code that writes code”
Source: http://xkcd.com/1629/ Source: http://www.memes.com/meme/487047
33. @oldJavaGuy#VoxxedBerlin
Why code generation?
• Everybody else is “doing it wrong”.
Style wars: e.g. instanceof vs getClass()
• Custom requirements: Serializable, Jackson or JPA
annotations
• Good news: you can do almost anything
• Bad news: you have to do almost everything yourself
• Most users will prefer “standard” solutions like Lombok or
AutoValue
34. @oldJavaGuy#VoxxedBerlin
Adding code generation to the Maven Build
• Maven has two dedicated lifecycle phases for code
generation,“generate-sources” and “generate-test-sources”
• The easiest way to achieve code generation is to execute a
Groovy script in one of these phases, using the Groovy
Maven Plugin (http://bit.ly/groovyMavenPlugin )
• By convention, Code generation uses the output folder
target/generated-sources/{generator-name}
• Never generate code to src folder!
39. @oldJavaGuy#VoxxedBerlin
Resolving types
class DtoGenerator { // continued
private AbstractJClass genType(GenericType type) {
def baseType = codeModel.ref(type.baseType)
def params = type.params.collect { resolveType(it) }
return baseType.narrow( params as AbstractJClass[] )
}
private AbstractJType resolveType(type) {
if (GenericType.class.isInstance(type)) return genType(type)
else return codeModel.ref(type)
}
} // continued
40. @oldJavaGuy#VoxxedBerlin
GETTERS
class DtoGenerator { // continued
private defineGetters(JDefinedClass c, Map fields) {
fields.each { e ->
def m = c.method(PUBLIC, resolveType(e.value),
e.value == 'boolean' ? 'is' : 'get'
+ LOWER_CAMEL.to(UPPER_CAMEL, e.key))
// return [property]
m.body()._return(THIS.ref(e.key))
}
}
} // continued
41. @oldJavaGuy#VoxxedBerlin
Constructor and Fields
class DtoGenerator { // continued
private defineConstructor(JDefinedClass c,
Map fields) {
def con = c.constructor(JMod.PUBLIC)
def body = con.body()
fields.each { e ->
def type = resolveType(e.value)
def f = c.field(PRIVATE | FINAL, type, e.key)
def param = con.param(type, e.key)
body.assign(THIS.ref(f), param)
} } } // continued
42. @oldJavaGuy#VoxxedBerlin
toString()
class DtoGenerator { // continued
private defineToStringMethod(JDefinedClass clazz, Map fields) {
def method = clazz.method(JMod.PUBLIC, String.class, "toString")
method.annotate(Override.class)
def body = method.body()
def invocation = codeModel.ref(MoreObjects.class)
.staticInvoke("toStringHelper").arg(THIS)
def current = invocation
fields.keySet().each { f ->
current = current.invoke(“add").arg(JExpr.lit(f))
.arg(THIS.ref(f)) }
body._return(current.invoke("toString"))
} } // continued
43. @oldJavaGuy#VoxxedBerlin
Value Objects (what else)
• Techniques I haven’t explored yet, but might in future:
• More efficient byte code generation (ByteBuddy)
• Interface-based proxies
• JEP 169 (http://openjdk.java.net/jeps/169)
44. @oldJavaGuy#VoxxedBerlin
Use Case: Library Patching
• Scenario:You have to use a third party library, which has
known defects
• Best choice: file an issue and / or submit a Pull Request to
the library owner
• I’ll assume this didn’t work, you are dependent on the library,
but you don’t want to fork it, since you want to stay current
• Techniques that will let you patch lib in an automated way
(ideally in a CI / CD pipeline)
45. @oldJavaGuy#VoxxedBerlin
Options
• If you have access to the source code, use a source code
parser and dynamically patch the sources
• Otherwise, manipulate byte code (change or intercept
existing code). Can be done statically at build time or
dynamically at class load time
• Create a static patch and write tests which make sure the
patch worked (I won’t explore this option)
46. @oldJavaGuy#VoxxedBerlin
Baseline
• As example I have written a trivial example class, with some
pretty stupid, but harmless bugs:
public class FicticiousExample {
public Integer yUNoReuseInteger(final int value) {
System.setProperty(RAN_BUGGY_CODE, TRUE);
return new Integer(value); }
public String yUStringConcatInLoop(Iterable<String> data, String delim) {
System.setProperty(RAN_BUGGY_CODE, TRUE);
String value = "";
final Iterator<String> iterator = data.iterator();
if (iterator.hasNext()) { value += iterator.next(); }
while (iterator.hasNext()) { value += delim + iterator.next(); }
return value;
}
}
47. @oldJavaGuy#VoxxedBerlin
Test suite
• In the test, I call the methods and assert that they work
correctly and that the system properties weren’t set
public abstract class FicticiousExamplePatchTest {
private FicticiousExample fe;
@After public void checkForEvilSystemProperty() {
assertThat(System.getProperty(RAN_BUGGY_CODE), nullValue()); }
@Before public void initObject() { fe = new FicticiousExample(); }
@Test public void assertCorrectIntegerBehavior() {
assertThat(fe.yUNoReuseInteger(123), is(sameInstance(123)));
assertThat(fe.yUNoReuseInteger(1234), not(sameInstance(1234)));
}
@Test public void assertCorrectStringBehavior() { // etc.
48. @oldJavaGuy#VoxxedBerlin
AspectJ
• https://eclipse.org/aspectj/
• Aspect-oriented language
(.aj format or Java with @AspectJ
annotations)
• ajc = AspectJ Compiler (after javac,
instead of javac)
• static compilation or load time
weaving through agent
• Docs are ancient / non-existent, use
mailing list or read the book:
http://bit.ly/ajInAction
50. @oldJavaGuy#VoxxedBerlin
AspectJ capabilities
• Extending / replacing / enriching code
• Inter-type declarations (~= Traits)
• Policy Enforcement (define custom compiler errors)
• Very flexible, can work on source or byte code
• Standard usage: Cross-cutting concerns (security, logging etc.)
51. @oldJavaGuy#VoxxedBerlin
Source Code Manipulation in the Build
Process
• Extract sources to generated-sources directory
• Parse and manipulate the sources (non-idempotent!?)
• Compile sources and distribute your library
52. @oldJavaGuy#VoxxedBerlin
JavaParser
• http://javaparser.github.io/javaparser/
• Parsers generated from JavaCC (Java Compiler Compiler) ->
complete Java 1.8 grammar support
• API not as friendly as JCodeModel (no management of types
and references etc.), but the only available fully functional Java
source code parser
• Again, I’ll be using Groovy to do the actual work. It could be
done in Java too, but the build setup would be more complex
53. @oldJavaGuy#VoxxedBerlin
Groovy Wrapper
public class Wrapper {
public exec(project, dir) {
def source = new File(dir, "...Example.java")
def compilationUnit = JavaParser.parse(source)
applyPatch(compilationUnit)
sourceFile.text = compilationUnit.toString()
project.compileSourceRoots.add(baseDir); }
private applyPatch(CompilationUnit unit) {
unit.accept(new PatchVisitor(), null) }
}
54. @oldJavaGuy#VoxxedBerlin
PatchVisitor
class PatchVisitor extends VoidVisitorAdapter<Void> {
public void visit(MethodDeclaration n, Object arg) {
if (n.name == "yUStringConcatInLoop") {
n.body = new BlockStmt() // delete existing body
patchStringMethod(n.body, n.parameters[0],
n.parameters[1])
} else if (n.name == "yUNoReuseInteger") {
n.body = new BlockStmt() // delete existing body
patchIntegerMethod(n.body, n.parameters[0])
} else super.visit(n, arg) }
55. @oldJavaGuy#VoxxedBerlin
PatchVisitor (Integer method)
private patchIntegerMethod(
BlockStmt b, Parameter p) {
def t = new ClassOrInterfaceType("Integer");
def tExpr = new TypeExpr(); tExpr.type = t
def mc = new MethodCallExpr(tExpr, "valueOf")
mc.args.add(new NameExpr(p.id.name))
b.getStmts().add(new ReturnStmt(mc))
}
// all this for
// return Integer.valueOf(i);
56. @oldJavaGuy#VoxxedBerlin
PatchVisitor (String method)
class PatchVisitor extends VoidVisitorAdapter<Void> { // continued
private patchStringMethod(BlockStmt blockStatement, Parameter iterable, Parameter delim) {
def sbType = new ClassOrInterfaceType("StringBuilder")
def sbId = new VariableDeclaratorId("sb")
def sbDecl = new VariableDeclarationExpr(sbType, [
new VariableDeclarator(sbId, new ObjectCreationExpr(null, sbType, []))
])
def itType = new ClassOrInterfaceType("Iterator<String>")
def itCall = new MethodCallExpr(new NameExpr(iterable.id.name), "iterator")
def itId = new VariableDeclaratorId("iterator")
def itDecl = new VariableDeclarationExpr(itType, [new VariableDeclarator(itId, itCall)])
def itExpr = new NameExpr(itId.name); def sbExpr = new NameExpr(sbId.name)
blockStatement.stmts.addAll([
new ExpressionStmt(sbDecl), new ExpressionStmt(itDecl),
new IfStmt(
new MethodCallExpr(itExpr, "hasNext"),
new BlockStmt([
new ExpressionStmt(new MethodCallExpr(sbExpr, "append", [new MethodCallExpr(itExpr, "next")])),
new WhileStmt(new MethodCallExpr(itExpr, "hasNext"), new BlockStmt([
new ExpressionStmt(new MethodCallExpr(
new MethodCallExpr(sbExpr, "append", [new NameExpr(delim.id.name)]),
"append", [new MethodCallExpr(itExpr, "next")]
))
]))
]),
null // <-- no else block
),
new ReturnStmt(new MethodCallExpr(sbExpr, "toString"))
])
}
}
57. @oldJavaGuy#VoxxedBerlin
PatchVisitor (String method)
class PatchVisitor extends VoidVisitorAdapter<Void> { // continued
private patchStringMethod(BlockStmt blockStatement, Parameter iterable, Parameter delim) {
def sbType = new ClassOrInterfaceType("StringBuilder")
def sbId = new VariableDeclaratorId("sb")
def sbDecl = new VariableDeclarationExpr(sbType, [
new VariableDeclarator(sbId, new ObjectCreationExpr(null, sbType, []))
])
def itType = new ClassOrInterfaceType("Iterator<String>")
def itCall = new MethodCallExpr(new NameExpr(iterable.id.name), "iterator")
def itId = new VariableDeclaratorId("iterator")
def itDecl = new VariableDeclarationExpr(itType, [new VariableDeclarator(itId, itCall)])
def itExpr = new NameExpr(itId.name); def sbExpr = new NameExpr(sbId.name)
blockStatement.stmts.addAll([
new ExpressionStmt(sbDecl), new ExpressionStmt(itDecl),
new IfStmt(
new MethodCallExpr(itExpr, "hasNext"),
new BlockStmt([
new ExpressionStmt(new MethodCallExpr(sbExpr, "append", [new MethodCallExpr(itExpr, "next")])),
new WhileStmt(new MethodCallExpr(itExpr, "hasNext"), new BlockStmt([
new ExpressionStmt(new MethodCallExpr(
new MethodCallExpr(sbExpr, "append", [new NameExpr(delim.id.name)]),
"append", [new MethodCallExpr(itExpr, "next")]
))
]))
]),
null // <-- no else block
),
new ReturnStmt(new MethodCallExpr(sbExpr, "toString"))
])
}
}
Source: http://www.memecenter.com/fun/1467675/my-eyes
58. @oldJavaGuy#VoxxedBerlin
The generated code, for comparison
public String yUStringConcatInLoop(
final Iterable<String> data, final String delim) {
StringBuilder sb = new StringBuilder();
Iterator<String> it = data.iterator();
if (it.hasNext()) {
sb.append(it.next());
while (it.hasNext()) {
sb.append(delim).append(it.next());
}
}
return sb.toString(); }
59. @oldJavaGuy#VoxxedBerlin
Tradeoff
• AST manipulation is hard, very
verbose and error prone
• But: It’s still better than trying to
do it with Regex (insert obligatory
Regex Cthulhu link here)
• friendlier Alternative:
walkmod.com (built on JavaParser,
“walkmod is an open source tool
to apply and share your own code
conventions.”)
Source: http://subgenius.wikia.com/wiki/Cthulhu
60. @oldJavaGuy#VoxxedBerlin
Use Case: Defect Analysis
• Identify bug patterns, reject
them at compile time
• Not mentioning the “good old”
tools: CheckStyle, PMD,
FindBugs.They are best used in
a separate CI build
• Focus on tools that hook
directly into the compile
process
Source: http://sequart.org/magazine/59883/cult-classics-starship-troopers/
61. @oldJavaGuy#VoxxedBerlin
Test Harness
public abstract class AbstractDefectDetectionTest extends AbstractCompilerTest {
private DefectAnalysisEngine engine;
@Before public void setupEngine() { this.engine = instantiateEngine(); }
@Test public void detectWellBehavedClass() {
CompilationResult result = engine.compile(sourceFileFor(wellBehavedClass()));
assertThat(result, isSuccess());
}
@Test public void detectIllBehavedClass() {
CompilationResult result = engine.compile(sourceFileFor(illBehavedClass()));
assertThat(result, isFailureWithExpectedMessage(expectedErrorMessage()));
}
protected abstract DefectAnalysisEngine instantiateEngine();
protected abstract Class<? extends WellBehaved> wellBehavedClass();
protected abstract Class<? extends IllBehaved> illBehavedClass();
protected abstract String expectedErrorMessage();
}
62. @oldJavaGuy#VoxxedBerlin
ForkedRun
• Helper class that calls a Java class in a separate process,
copying the Classpath from the local context, abstracting the
output away to a CompilationResult class, that we can run
matchers against.
• Fluent API with matchers for converting classpath to
bootclasspath and other nice features
• http://bit.ly/forkedRun
63. @oldJavaGuy#VoxxedBerlin
ForkedRun (sample)
public final CompilationResult run() {
final Set<String> classPath = new LinkedHashSet<>();
final Set<String> bootPath = new LinkedHashSet<>();
try {
dispatchClassPath(classPathElements, bootPathElements);
String javaExe = getExecutable();
List<String> cmds = buildCommands(classPath, bootPath, javaExe);
ProcessBuilder processBuilder = new ProcessBuilder().command(cmds);
if (outputCommand) System.out.println(Joiner.on(' ').join(commands));
Process proc = processBuilder.start();
List<String> errorMsg = gatherOutput(proc);
int status = proc.waitFor();
return new CompilationResult(status == 0, errorMsg);
} catch (InterruptedException | IOException | URISyntaxException e) {
throw new IllegalStateException(e); } }
64. @oldJavaGuy#VoxxedBerlin
False positives
• Example: Immutability (impossible to reliably detect, by any
technology known to me)
public final class ImmutableUser{
private final String name; private final Date birthDate;
private final List<String> nickNames;
public ImmutableUser(String name, List<String> nickNames, Date birthDate) {
this.name = name;
this.nickNames = ImmutableList.copyOf(nickNames);
this.birthDate = new Date(birthDate.getTime()); }
public String getName() { return name; }
public List<String> getNickNames() { return ImmutableList.copyOf(nickNames); }
public Date getBirthDate() { return new Date(birthDate.getTime()); }
}
65. @oldJavaGuy#VoxxedBerlin
What can we detect?
• Forbidden classes, erroneous usages
• Package-level architecture restrictions
(MicroServices or OSGI are a better solution)
• Implementation inconsistent with annotations or interface
(e.g. Nullness)
66. @oldJavaGuy#VoxxedBerlin
Google Error Prone
• http://errorprone.info/
• Google 20% project
• Wrapper around javac, with compatible API
• Many defined bug-patterns, most specific to Google (Android,
Protobuf, Gwt, Guice)
• New Bug Patterns can only be added via Pull Request to
Google :-(
• Integrated with Maven, Gradle,Ant etc.
67. @oldJavaGuy#VoxxedBerlin
Obscure bug patterns
• Example: Regex bug detection
public class IllBehavedRegex {
static List<String> splitByAlpha(String s) {
return Arrays.asList(
s.split("[a-z")); // bad pattern
}
}
68. @oldJavaGuy#VoxxedBerlin
Calling the engine in a test
public class ErrorProneEngine implements DefectAnalysisEngine {
private final Set<String> checks;
public ErrorProneEngine(Set<String> checks) { this.checks = checks; }
@Override public CompilationResult compile(final File sourceFile) {
return new ForkedRun(ErrorProneAnalysisEngine.class)
.withAdditionalClassLoaderFromClass(AbstractUser.class)
.withBootClassPathMatcher("com", "google", "errorprone")
.withBootClassPathMatcher("org", "checkerframework")
.withArg(ErrorProneCompiler.class)
.withArg("-d").tempDirAsArg()
.withArg("-Xep:" + Joiner.on(',').join(this.checks))
.withArg(sourceFile.getAbsolutePath())
.run();
} }
69. @oldJavaGuy#VoxxedBerlin
Checker Framework
• http://types.cs.washington.edu/checker-framework/
• The Checker Framework enhances Java’s type system to make
it more powerful and useful.This lets software developers
detect and prevent errors in their Java programs.The Checker
Framework includes compiler plug-ins ("checkers") that find
bugs or verify their absence. It also permits you to write your
own compiler plug-ins.
• Disadvantage: needs to be installed separately, hard to
integrate in a build system
• But: checkers can be used as plain annotation processors
70. @oldJavaGuy#VoxxedBerlin
Java 8 Type Annotations
• As of the Java SE 8 release,
annotations can also be applied to
any type use […] A few examples
of where types are used are class
instance creation expressions
(new), casts, implements clauses,
and throws clauses.
http://bit.ly/typeAnnotations
• The Checker Framework
embraces these new annotation
usages
Source: http://memegenerator.net/
71. @oldJavaGuy#VoxxedBerlin
Checker Framework Engine
public class CheckerFrameworkAnalysisEngine implements DefectAnalysisEngine {
private final Class<? extends BaseTypeChecker> checkerClass;
public CheckerFrameworkAnalysisEngine(Class<? extends BaseTypeChecker> c) {
this.checkerClass = c;
}
@Override public CompilationResult compile(final File sourceFile) {
return new ForkedRun(CheckerFrameworkAnalysisEngine.class)
.withAdditionalClassLoaderFromClass(AbstractUser.class)
.withJavaC() // javac, not java
.withArg("-d").tempDirAsArg()
.withArg("-processor").withArg(checkerClass)
.withArg(sourceFile.getAbsolutePath())
.run(); }
}
72. @oldJavaGuy#VoxxedBerlin
Example: Nullness
public class WellbehavedNullness {
@PolyNull String nullInOut(@PolyNull String s) {
if (s == null) return s;
return s.toUpperCase().trim();
}
@MonotonicNonNull private String initallyNull;
public void assignField(@NonNull String value) {
initallyNull = checkNotNull(value);
}
@Nonnull public String getValue() {
if (initallyNull == null)
initallyNull = "wasNull";
return initallyNull;
} }
73. @oldJavaGuy#VoxxedBerlin
Example: Nullness
public class WellbehavedNullness {
@PolyNull String nullInOut(@PolyNull String s) {
if (s == null) return s;
return s.toUpperCase().trim();
}
@MonotonicNonNull private String initallyNull;
public void assignField(@NonNull String value) {
initallyNull = checkNotNull(value);
}
@Nonnull public String getValue() {
if (initallyNull == null)
initallyNull = "wasNull";
return initallyNull;
} }
Source: https://imgflip.com/memegenerator
74. @oldJavaGuy#VoxxedBerlin
AspectJ (again)
• AspectJ allows custom compiler
errors, according to static checks
• Architecture checks: package a may
not access package b
• Forbidden usage patterns: e.g. Spring
MVC controller may not take
OutputStream param
• Forbidden classes: Enforce
deprecation of legacy classes
• Most of these problems can be solved
differently (MicroServices etc.)
Source: http://www.someecards.com/usercards/viewcard/MjAxMy1jZWRhODllNTI3YWI4Yjkz
75. @oldJavaGuy#VoxxedBerlin
Forbid usage of deprecated types
public aspect PolicyEnforcementAspect{
pointcut badCall() : call(* Hashtable.*(..))
|| call(Hashtable.new(..))
|| call(* Vector.*(..))
|| call(Vector.new(..));
declare error : badCall()
"Hashtable and Vector are deprecated!";
}
76. @oldJavaGuy#VoxxedBerlin
AspectJ testing engine
public class AspectJPolicyEnforcementEngine
implements DefectAnalysisEngine {
@Override public CompilationResult compile(File sourceFile) {
final File aspectFile = findAspectFile(sourceFile);
return new ForkedRun(AspectJPolicyEnforcementEngine.class)
.withArg(Main.class /* ajc */).withArg("-1.8")
.withArg("-target").withArg("1.8")
.withArg("-d").tempDirAsArg()
.withArg(sourceFile.getAbsolutePath())
.withArg(aspectFile.getAbsolutePath())
.run(); }
77. @oldJavaGuy#VoxxedBerlin
Overview of discussed techniques
• Obviously, this is an opinion, not advice. Use at your own risk.
• Author is not affiliated with any of the above libraries.
Technique Have I used in real applications? Do I recommend technique?
Lombok yes maybe
AutoValue yes yes
CGLib BeanGenerator no no
JCodeModel yes yes
AspectJ (patching) yes maybe
JavaParser yes maybe
ErrorProne no maybe
Checker Framework no yes
AspectJ (policy enforcement) yes yes
78. @oldJavaGuy#VoxxedBerlin
Where to go from here
• Look at the github code, send me a PR if you have
improvements
• Contact me if you have questions
• Suggest more techniques / use cases