Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
blank_issues_enabled: false
contact_links:
- name: 💬 Discussions
url: https://github.com/javaevolved/javaevolved.github.io/discussions
about: Ask questions, share ideas, or discuss patterns.
3 changes: 2 additions & 1 deletion .github/workflows/build-generator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
- '.github/workflows/build-generator.yml'
- 'html-generators/generate.java'
- 'html-generators/generateog.java'
- 'html-generators/og/**'
- 'agent-plugins/modern-java-development/skills/modern-java/scripts/DetectJavaVersion.java'
schedule:
- cron: '0 6 * * 1' # every Monday at 06:00 UTC
Expand Down Expand Up @@ -67,7 +68,7 @@ jobs:
path: |
html-generators/generateog.jar
html-generators/generateog.aot
key: generateog-${{ hashFiles('html-generators/generateog.java') }}
key: generateog-${{ hashFiles('html-generators/generateog.java', 'html-generators/og/**') }}

build-detect-java-version:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ jobs:
path: |
html-generators/generateog.jar
html-generators/generateog.aot
key: generateog-${{ hashFiles('html-generators/generateog.java') }}
key: generateog-${{ hashFiles('html-generators/generateog.java', 'html-generators/og/**') }}

- name: Generate OG cards with cached JAR + AOT
if: steps.changes.outputs.og == 'true' && steps.cache-restore-og.outputs.cache-hit == 'true'
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ A collection of side-by-side code comparisons showing old Java patterns next to

🔗 **[javaevolved.dev](https://javaevolved.dev)**

[![GitHub Pages](https://img.shields.io/badge/GitHub%20Pages-live-brightgreen)](https://javaevolved.github.io)
[![GitHub Pages](https://img.shields.io/badge/GitHub%20Pages-live-brightgreen)](https://javaevolved.dev)
[![Snippets](https://img.shields.io/badge/snippets-112-blue)](#categories)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Contributions welcome](https://img.shields.io/badge/contributions-welcome-orange)](#contributing)
Expand Down
12 changes: 6 additions & 6 deletions agent-plugins/modern-java-development/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ modern-java-development/
## Install

Versioned `.tar.gz` packages and SHA-256 checksums are available from the
[GitHub Releases](https://github.com/javaevolved/javaevolved.github.io/releases).
[GitHub Releases](https://github.com/brunoborges/javaevolved/releases).
Each archive contains the `modern-java-development` package directory.

### GitHub Copilot CLI
Expand All @@ -40,7 +40,7 @@ GitHub Copilot CLI supports the Agent Plugins specification. Add the
java.evolved marketplace once:

```bash
copilot plugin marketplace add javaevolved/javaevolved.github.io
copilot plugin marketplace add brunoborges/javaevolved
```

Then install the plugin:
Expand All @@ -59,9 +59,9 @@ Claude Code supports the Agent Skills format used by the `modern-java` skill.
Clone this repository and copy the skill to your personal skills directory:

```bash
git clone --depth 1 https://github.com/javaevolved/javaevolved.github.io.git
git clone --depth 1 https://github.com/brunoborges/javaevolved.git
mkdir -p ~/.claude/skills
cp -R javaevolved.github.io/agent-plugins/modern-java-development/skills/modern-java \
cp -R javaevolved/agent-plugins/modern-java-development/skills/modern-java \
~/.claude/skills/
```

Expand All @@ -75,9 +75,9 @@ Codex CLI also supports Agent Skills. Clone this repository and copy the skill
to your personal skills directory:

```bash
git clone --depth 1 https://github.com/javaevolved/javaevolved.github.io.git
git clone --depth 1 https://github.com/brunoborges/javaevolved.git
mkdir -p ~/.agents/skills
cp -R javaevolved.github.io/agent-plugins/modern-java-development/skills/modern-java \
cp -R javaevolved/agent-plugins/modern-java-development/skills/modern-java \
~/.agents/skills/
```

Expand Down
6 changes: 3 additions & 3 deletions agent-plugins/modern-java-development/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
"description": "Version-aware guidance for writing, reviewing, and modernizing Java projects.",
"author": {
"name": "java.evolved",
"url": "https://javaevolved.github.io"
"url": "https://javaevolved.dev"
},
"homepage": "https://javaevolved.github.io",
"repository": "https://github.com/javaevolved/javaevolved.github.io",
"homepage": "https://javaevolved.dev",
"repository": "https://github.com/brunoborges/javaevolved",
"license": "MIT",
"keywords": [
"java",
Expand Down
8 changes: 4 additions & 4 deletions blogs/replacing-batik-with-graphics2d.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Replacing Apache Batik with Graphics2D: How We Made Our Java OG Card Generator Faster Than Python

*March 2026 · [javaevolved.github.io](https://javaevolved.github.io)*
*March 2026 · [javaevolved.dev](https://javaevolved.dev)*

---

[Java Evolved](https://javaevolved.github.io) is a static site showcasing 112 modern Java patterns across 11 categories — each with a side-by-side "old vs modern" code comparison. For every pattern, we generate an Open Graph card: a 1200×630 PNG image used when links are shared on social media.
[Java Evolved](https://javaevolved.dev) is a static site showcasing 112 modern Java patterns across 11 categories — each with a side-by-side "old vs modern" code comparison. For every pattern, we generate an Open Graph card: a 1200×630 PNG image used when links are shared on social media.

This is the story of how we replaced Apache Batik with plain `Graphics2D`, split a monolithic script into modules using JBang, and tuned the JVM to squeeze out every last bit of performance — ending up faster than Python.

Expand Down Expand Up @@ -236,6 +236,6 @@ java -XX:AOTCacheOutput=html-generators/generateog.aot -jar html-generators/gene
java -XX:Tier4CompileThreshold=100 -XX:AOTCache=html-generators/generateog.aot -jar html-generators/generateog.jar
```

The full source is at [github.com/javaevolved/javaevolved.github.io](https://github.com/javaevolved/javaevolved.github.io) under `html-generators/`.
The full source is at [github.com/brunoborges/javaevolved](https://github.com/brunoborges/javaevolved) under `html-generators/`.

CI benchmark results: [Actions run #22563953466](https://github.com/javaevolved/javaevolved.github.io/actions/runs/22563953466).
CI benchmark results: [Actions run #22563953466](https://github.com/brunoborges/javaevolved/actions/runs/22563953466).
6 changes: 3 additions & 3 deletions html-generators/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ This produces a self-contained ~2.2 MB JAR with all dependencies (Jackson) bundl

Two GitHub Actions workflows automate the build and deploy pipeline:

1. **`build-generator.yml`** — Triggered when `generate.java` changes on `main`. Uses JBang to rebuild the fat JAR and commits the updated `generate.jar` back to the repository.
1. **`build-generator.yml`** — Triggered when generator sources change on `main`, including `generate.java`, `generateog.java`, and `og/**`. Uses JBang to rebuild the fat JARs and saves them with their AOT caches in GitHub Actions caches. The OG cache key includes the renderer sources so branding and rendering changes invalidate stale builds.

2. **`deploy.yml`** — Triggered when content, templates, the JAR, or site assets change on `main`. Runs `java -jar html-generators/generate.jar` to regenerate all HTML pages, `snippets.json`, and `index.html`, then deploys the `site/` folder to GitHub Pages.
2. **`deploy.yml`** — Triggered when content, templates, site assets, or OG sources change on `main`, or after a successful generator build. Restores matching JARs and AOT caches, falling back to JBang on a cache miss, to regenerate the HTML, `snippets.json`, and OG cards. It then deploys the `site/` folder to GitHub Pages at `https://javaevolved.dev/`.

This means the deploy workflow always uses the pre-built fat JAR (no JBang required at deploy time), and the JAR stays in sync with the source automatically.
Both workflows use matching source-based cache keys, keeping deployed output in sync with the generator sources.
6 changes: 3 additions & 3 deletions html-generators/generate.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* Generate HTML detail pages from JSON snippet files and slug-template.html.
* Generates the static site from the content and translation sources.
*/
static final String BASE_URL = "https://javaevolved.github.io";
static final String BASE_URL = "https://javaevolved.dev";
static final String CONTENT_DIR = "content";
static final String SITE_DIR = "site";
static final String TRANSLATIONS_DIR = "translations";
Expand Down Expand Up @@ -506,7 +506,7 @@ String renderProofSection(Snippet s, Map<String, String> strings) {
var pascal = slugToPascalCase(s.slug());
var proofFile = Path.of("proof", s.category(), pascal + ".java");
if (!Files.exists(proofFile)) return "";
var proofUrl = "https://github.com/javaevolved/javaevolved.github.io/blob/main/proof/%s/%s.java"
var proofUrl = "https://github.com/brunoborges/javaevolved/blob/main/proof/%s/%s.java"
.formatted(s.category(), pascal);
var label = strings.getOrDefault("sections.proof", "Proof");
var linkText = strings.getOrDefault("sections.proofLink", "View proof source");
Expand Down Expand Up @@ -607,7 +607,7 @@ void generateTopicPages(Templates templates, SequencedMap<String, Snippet> allSn
IO.println("Generated %d topic pages".formatted(tagSnippets.size()));
}

static final String GITHUB_ISSUES_URL = "https://github.com/javaevolved/javaevolved.github.io/issues/new";
static final String GITHUB_ISSUES_URL = "https://github.com/brunoborges/javaevolved/issues/new";

Map<String, String> buildContributeUrls(Snippet s, String locale, String localeName) {
var codeUrl = "%s?template=code-issue.yml&title=%s&category=%s&slug=%s".formatted(
Expand Down
2 changes: 1 addition & 1 deletion html-generators/og/PngRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ static void drawFooter(Graphics2D g, Snippet s) {
// Brand (right-aligned)
g.setFont(brandFont);
g.setColor(Palette.color(ACCENT));
var brand = "javaevolved.github.io";
var brand = "javaevolved.dev";
var fm = g.getFontMetrics(brandFont);
g.drawString(brand, W - PAD - fm.stringWidth(brand), H - 22);
}
Expand Down
2 changes: 1 addition & 1 deletion html-generators/og/SvgRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public static String generate(Snippet s) {

<!-- Footer -->
<text x="%d" y="%d" class="footer">JDK %s+</text>
<text x="%d" y="%d" class="brand" text-anchor="end">javaevolved.github.io</text>
<text x="%d" y="%d" class="brand" text-anchor="end">javaevolved.dev</text>
</svg>
""".formatted(
// viewBox
Expand Down
6 changes: 3 additions & 3 deletions specs/i18n/i18n-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,9 +359,9 @@ The `<html>` opening tag becomes `<html lang="{{locale}}">`.
`hreflang` alternate links are generated for every supported locale:

```html
<link rel="alternate" hreflang="en" href="https://javaevolved.github.io/language/type-inference-with-var.html">
<link rel="alternate" hreflang="pt-BR" href="https://javaevolved.github.io/pt-BR/language/type-inference-with-var.html">
<link rel="alternate" hreflang="x-default" href="https://javaevolved.github.io/language/type-inference-with-var.html">
<link rel="alternate" hreflang="en" href="https://javaevolved.dev/language/type-inference-with-var.html">
<link rel="alternate" hreflang="pt-BR" href="https://javaevolved.dev/pt-BR/language/type-inference-with-var.html">
<link rel="alternate" hreflang="x-default" href="https://javaevolved.dev/language/type-inference-with-var.html">
```

---
Expand Down
2 changes: 1 addition & 1 deletion specs/social-posts-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Each tweet is stored in `social/tweets/{category}/{slug}.yaml` so pattern pull r

{oldLabel} → {modernLabel} (JDK {jdkVersion}+)

🔗 https://javaevolved.github.io/{category}/{slug}.html
🔗 https://javaevolved.dev/{category}/{slug}.html

#Java #JavaEvolved
```
Expand Down
22 changes: 11 additions & 11 deletions templates/agent-plugin.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<title>Modern Java Agent Plugin | java.evolved</title>
<meta name="description" content="Install the java.evolved agent plugin for Java-version-aware development, reviews, refactoring, and modernization guidance.">
<meta name="robots" content="index, follow">
<link rel="canonical" href="https://javaevolved.github.io/agent-plugin.html">
<link rel="canonical" href="https://javaevolved.dev/agent-plugin.html">
<link rel="preload" href="/assets/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/assets/fonts/jetbrains-mono.woff2" as="font" type="font/woff2" crossorigin>
<link rel="icon" href="/favicon.ico" sizes="any">
Expand All @@ -22,9 +22,9 @@
<meta name="theme-color" content="#f97316">
<meta property="og:title" content="Modern Java Agent Plugin | java.evolved">
<meta property="og:description" content="Version-aware guidance for writing, reviewing, and modernizing Java projects.">
<meta property="og:url" content="https://javaevolved.github.io/agent-plugin.html">
<meta property="og:url" content="https://javaevolved.dev/agent-plugin.html">
<meta property="og:type" content="website">
<meta property="og:image" content="https://javaevolved.github.io/images/social-card.png">
<meta property="og:image" content="https://javaevolved.dev/images/social-card.png">
<style>
@font-face{font-family:'Inter';font-style:normal;font-weight:100 900;font-display:swap;src:url('/assets/fonts/inter.woff2') format('woff2')}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400 700;font-display:swap;src:url('/assets/fonts/jetbrains-mono.woff2') format('woff2')}
Expand All @@ -40,7 +40,7 @@
<a href="/" class="logo">java.<span>evolved</span></a>
<div class="nav-right">
<a href="/#all-comparisons" class="plugin-nav-link">Patterns</a>
<a href="https://github.com/javaevolved/javaevolved.github.io/tree/main/agent-plugins/modern-java-development" target="_blank" rel="noopener" class="github-link" aria-label="View the agent plugin on GitHub">
<a href="https://github.com/brunoborges/javaevolved/tree/main/agent-plugins/modern-java-development" target="_blank" rel="noopener" class="github-link" aria-label="View the agent plugin on GitHub">
<svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<circle cx="10" cy="10" r="9" fill="none" stroke="currentColor" stroke-width="1.5"/>
<path d="M10 3C6.13 3 3 6.13 3 10c0 3.09 2 5.71 4.77 6.63.35.06.48-.15.48-.33v-1.16c-1.95.42-2.36-1.07-2.36-1.07-.32-.81-.78-1.03-.78-1.03-.64-.43.05-.42.05-.42.7.05 1.07.72 1.07.72.63 1.08 1.65.77 2.05.59.06-.46.24-.77.44-.95-1.57-.18-3.22-.78-3.22-3.48 0-.77.27-1.4.72-1.89-.07-.18-.31-.9.07-1.87 0 0 .59-.19 1.93.72.56-.16 1.16-.24 1.76-.24s1.2.08 1.76.24c1.34-.91 1.93-.72 1.93-.72.38.97.14 1.69.07 1.87.45.49.72 1.12.72 1.89 0 2.71-1.65 3.3-3.23 3.47.25.22.48.65.48 1.31v1.94c0 .19.13.4.48.33C15 15.71 17 13.09 17 10c0-3.87-3.13-7-7-7z"/>
Expand All @@ -59,7 +59,7 @@ <h1>Modern Java advice,<br>bounded by your JDK.</h1>
<p>The java.evolved agent plugin detects the Java version your project actually targets, then recommends only the final language features, APIs, and practices that version supports.</p>
<div class="plugin-hero-actions">
<a href="#install" class="primary-action">Install the plugin <span aria-hidden="true">↓</span></a>
<a href="https://github.com/javaevolved/javaevolved.github.io/tree/main/agent-plugins/modern-java-development" target="_blank" rel="noopener" class="secondary-action">View source</a>
<a href="https://github.com/brunoborges/javaevolved/tree/main/agent-plugins/modern-java-development" target="_blank" rel="noopener" class="secondary-action">View source</a>
</div>
</div>
<div class="detector-terminal" aria-label="Example Java version detection result">
Expand Down Expand Up @@ -155,7 +155,7 @@ <h3>GitHub Copilot</h3>
<p>Add the java.evolved marketplace once, then install the plugin.</p>
</div>
<div class="install-command">
<code>copilot plugin marketplace add javaevolved/javaevolved.github.io</code>
<code>copilot plugin marketplace add brunoborges/javaevolved</code>
<button class="command-copy-btn" type="button" aria-label="Copy command">
<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path d="M5.75 1.5h6.75a2 2 0 0 1 2 2v6.75a2 2 0 0 1-2 2h-1V9.5a5 5 0 0 0-5-5H3.5v-1a2 2 0 0 1 2-2h.25Zm-2.25 4h3a4 4 0 0 1 4 4v3a2 2 0 0 1-2 2h-5a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2Z" fill="currentColor"/></svg>
</button>
Expand All @@ -174,13 +174,13 @@ <h3>Claude Code</h3>
<p>Clone the repository, then install the skill for your user account.</p>
</div>
<div class="install-command">
<code>git clone --depth 1 https://github.com/javaevolved/javaevolved.github.io.git</code>
<code>git clone --depth 1 https://github.com/brunoborges/javaevolved.git</code>
<button class="command-copy-btn" type="button" aria-label="Copy command">
<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path d="M5.75 1.5h6.75a2 2 0 0 1 2 2v6.75a2 2 0 0 1-2 2h-1V9.5a5 5 0 0 0-5-5H3.5v-1a2 2 0 0 1 2-2h.25Zm-2.25 4h3a4 4 0 0 1 4 4v3a2 2 0 0 1-2 2h-5a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2Z" fill="currentColor"/></svg>
</button>
</div>
<div class="install-command">
<code>mkdir -p ~/.claude/skills &amp;&amp; cp -R javaevolved.github.io/agent-plugins/modern-java-development/skills/modern-java ~/.claude/skills/</code>
<code>mkdir -p ~/.claude/skills &amp;&amp; cp -R javaevolved/agent-plugins/modern-java-development/skills/modern-java ~/.claude/skills/</code>
<button class="command-copy-btn" type="button" aria-label="Copy command">
<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path d="M5.75 1.5h6.75a2 2 0 0 1 2 2v6.75a2 2 0 0 1-2 2h-1V9.5a5 5 0 0 0-5-5H3.5v-1a2 2 0 0 1 2-2h.25Zm-2.25 4h3a4 4 0 0 1 4 4v3a2 2 0 0 1-2 2h-5a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2Z" fill="currentColor"/></svg>
</button>
Expand All @@ -194,13 +194,13 @@ <h3>OpenAI Codex CLI</h3>
<p>Clone the repository, then install the skill for your user account.</p>
</div>
<div class="install-command">
<code>git clone --depth 1 https://github.com/javaevolved/javaevolved.github.io.git</code>
<code>git clone --depth 1 https://github.com/brunoborges/javaevolved.git</code>
<button class="command-copy-btn" type="button" aria-label="Copy command">
<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path d="M5.75 1.5h6.75a2 2 0 0 1 2 2v6.75a2 2 0 0 1-2 2h-1V9.5a5 5 0 0 0-5-5H3.5v-1a2 2 0 0 1 2-2h.25Zm-2.25 4h3a4 4 0 0 1 4 4v3a2 2 0 0 1-2 2h-5a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2Z" fill="currentColor"/></svg>
</button>
</div>
<div class="install-command">
<code>mkdir -p ~/.agents/skills &amp;&amp; cp -R javaevolved.github.io/agent-plugins/modern-java-development/skills/modern-java ~/.agents/skills/</code>
<code>mkdir -p ~/.agents/skills &amp;&amp; cp -R javaevolved/agent-plugins/modern-java-development/skills/modern-java ~/.agents/skills/</code>
<button class="command-copy-btn" type="button" aria-label="Copy command">
<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path d="M5.75 1.5h6.75a2 2 0 0 1 2 2v6.75a2 2 0 0 1-2 2h-1V9.5a5 5 0 0 0-5-5H3.5v-1a2 2 0 0 1 2-2h.25Zm-2.25 4h3a4 4 0 0 1 4 4v3a2 2 0 0 1-2 2h-5a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2Z" fill="currentColor"/></svg>
</button>
Expand All @@ -214,7 +214,7 @@ <h3>OpenAI Codex CLI</h3>

<footer>
<p><a href="/">java.evolved</a> — Java has evolved. Your code can too.</p>
<p><a href="https://github.com/javaevolved/javaevolved.github.io/tree/main/agent-plugins/modern-java-development" target="_blank" rel="noopener">View the agent plugin on GitHub</a></p>
<p><a href="https://github.com/brunoborges/javaevolved/tree/main/agent-plugins/modern-java-development" target="_blank" rel="noopener">View the agent plugin on GitHub</a></p>
</footer>

<script src="/app.js"></script>
Expand Down
Loading
Loading