Zum Hauptinhalt springen

What's new in version 25.10?

· 7 Min lesen
webforJ Team
webforJ Development Team

cover image

webforJ version 25.10 introduces some heavy hitting new capabilities for building global, secure, and integrated applications. This release brings internationalization support, enterprise-grade security which includes Spring Security integration, Webswing compatibility for legacy Java Swing apps, and adds to our Login component.

As always, see the GitHub release overview for a more comprehensive list of changes. Highlighted below are some of the most exciting changes:

Webswing integration for progressive modernization

To kick things off, webforJ is excited to announce our partnership with Webswing! With this collaboration, developers now have a powerful set of tools to being legacy Java Swing apps directly to the browser, and a roadmap for piecewise modernization that takes the risk and complexity out of an otherwise complex and difficult transition.

If you or your company currently have a Java Swing application that needs to be modernized, webforJ 25.10 brings Webswing integration, which lets you embed existing Swing applications directly in your webforJ apps with zero code changes to the Swing app itself.

@Route
public class SwingAppView extends Composite<Div> {
public SwingAppView() {
WebswingConnector connector = new WebswingConnector("http://localhost:8080/myapp/");
connector.setSize("100%", "600px");
getBoundComponent().add(connector);
}
}

The new WebswingConnector component streams your Swing app to browsers, giving users immediate web access. But here's the exciting part: you can incrementally replace Swing components with modern webforJ equivalents at your own pace.

Start by embedding the entire app, then gradually modernize high-value components like forms and dialogs while preserving critical business logic. Bidirectional communication keeps both sides synchronized throughout the journey. This approach is perfect for organizations with complex domain logic that would be risky to recreate, or when time and cost constraints make a full rewrite impractical.

Try it yourself

Want to see progressive modernization in action? Check out the complete tutorial with working source code that shows how to modernize a customer management app step-by-step.

Info

Check out the Webswing integration docs for setup instructions and the modernization tutorial for implementation details.

Route Security with Spring Security integration

webforJ 25.10 introduces Route Security - a declarative security system that protects your routes with simple annotations. Whether using this in tandem with the integrated Spring Security support, or implementing an existing or custom solution, you no longer need to implement authentication checks or complex authorization layers. Just annotate your routes, and the framework handles the rest.

Protecting routes with annotations
@Route("/login")
@AnonymousAccess // Public access
public class LoginView extends Composite<Login> { }

@Route("/dashboard")
public class DashboardView extends Composite<Div> { } // Requires authentication

@Route("/admin")
@RolesAllowed("ADMIN") // Requires ADMIN role
public class AdminView extends Composite<Div> { }

Spring Security is supported out of the box for teams using Spring Boot, and is recommended for those starting a new project. It's built on an extensible architecture that works with custom authentication systems too. Use SpEL expressions for complex authorization logic, create custom evaluators for business-specific rules, and enable secure-by-default mode to require authentication for all routes unless explicitly marked public.

The security system handles both authentication (verifying who the user is) and authorization (verifying what they can access). Rules are automatically enforced before any component renders, providing centralized, consistent protection across your entire app without manual checks in each view.

Info

Check out the complete Security documentation for implementation guides, Spring Security integration details, and architectural patterns.

Internationalization and localization support

Building global applications just got easier. webforJ 25.10 introduces a localization system with automatic locale change notifications. Implement the LocaleObserver interface in your components, and they'll automatically receive updates when users switch languages - no manual event wiring required.

public class NavigationMenu extends Composite<FlexLayout> implements LocaleObserver {
@Override
public void onLocaleChange(LocaleEvent event) {
// Automatically called when locale changes
bundle = ResourceBundle.getBundle("messages", event.getLocale());
updateAllLabels();
}
}

When your app calls App.setLocale(), every component implementing LocaleObserver gets notified instantly. The system works with Java's ResourceBundle API for traditional property file translations, but you can also load translations from databases, REST APIs, or any custom source. One line of code triggers coordinated updates across your entire application - navigation menus, forms, dialogs, everything.

The framework automatically handles observer registration and cleanup through component lifecycle hooks - no memory leaks, no manual subscription management.

TODO

For more information, see this section of the docs to learn more.

Login component enhancements

The Login component gets two key upgrades that pair perfectly with the new Route Security system. First, form action support via setAction() enables traditional POST-based authentication - just point it at your Spring Security endpoint and it handles the rest.

Second, custom fields support lets you extend authentication workflows with department codes, 2FA tokens, tenant identifiers, or whatever your auth system requires. Both enhancements maintain full backward compatibility with existing onSubmit() handlers.

Textual date parsing for masked date fields

The MaskedDateField component now supports textual date parsing, bringing human-friendly date formats to your forms. Want to display "September 15, 2025" or "Mon 09/15/25" and have it work with spin controls, validation, and programmatic updates? Now you can.

MaskedDateField dateField = new MaskedDateField();
dateField.setMask("%Ds %Ml/%Dz/%Yz"); // "Mon September/15/25"
dateField.setTextualDateParsing(true); // Enable textual parsing

The component parses both short and long month names ("Sep" or "September"), recognizes day names as decorative elements, and handles everything case-insensitively. It's locale-aware too - French, German, whatever your users need. Numeric input still works exactly as before, maintaining full backward compatibility.

This means your forms can use natural date formats that users actually prefer. Enable it with one method call and the component handles the rest.

Info

See the Masked Date Field documentation for format masks and configuration options.

Flexible entity key identification for repositories

Repositories need to identify entities for operations like find() and item selection. You can implement HasEntityKey in your entity classes to define their identity, but what about scenarios where you can't or don't want to modify the entity? Think third-party domain models, generated classes, or existing codebases where adding interfaces isn't practical.

The new setKeyProvider() method accepts method references pointing to your entity's ID getter. No interface implementation required, no entity modifications needed. This is particularly valuable when working with entities you can't control—just point the repository at the existing ID field and you're done.

CollectionRepository<Product> repository = new CollectionRepository<>(products);
repository.setKeyProvider(Product::getId); // That's it

// Now repository operations just work
Product item = repository.find("PROD-123");

HasEntityKey remains available for cases where entities should self-define their identity or when key extraction logic is complex. Choose whichever approach fits your architecture.

Info

See the Repository documentation for both entity identification approaches and when to use each.

That wraps up the major features and functionality introduced in webforJ 25.10. As always, see the GitHub release overview for a more comprehensive list of changes.