GOSS is a JMS-based messaging framework providing client/server architecture, request/response patterns, and security integration for distributed power grid applications. It serves as the foundation for GridAPPS-D and other grid simulation platforms.
- ActiveMQ 6.2.0 with Jakarta JMS 3.1 (from javax.jms)
- Apache Shiro 2.0.0 (from 1.x)
- Jakarta EE APIs (from Java EE)
- Spring Framework 6.x, Jackson 2.18.x, SLF4J 2.0.x
See the JDK 21 Upgrade section below for details.
- OpenJDK 21 (or compatible JDK 21 distribution)
- Gradle 8.10+ (included via wrapper)
1. Clone the repository:
git clone https://github.com/GridOPTICS/GOSS.git
cd GOSS2. Build and run (choose one):
./gradlew :pnnl.goss.core.runner:createSimpleRunner
java -jar pnnl.goss.core.runner/generated/executable/goss-simple-runner.jar- Size: ~33 MB
- Type: Fat JAR with all dependencies
- Use case: Quick testing, development
./gradlew buildRunner.goss-core
java -jar pnnl.goss.core.runner/generated/runners/goss-core-runner.jar- Size: ~62 MB
- Type: Apache Felix OSGi framework with bundles
- Use case: Production, modular deployments
- Includes: Updated dependencies (ActiveMQ 6.2.0, Jakarta JMS, Shiro 2.0)
./gradlew buildRunner.goss-core-ssl
java -jar pnnl.goss.core.runner/generated/runners/goss-core-ssl-runner.jar3. Verify GOSS is running:
Once started, you can use these Gogo shell commands:
gs:listDataSources - Lists registered datasources
gs:listHandlers - Lists registered request handlers
GOSS includes a BndRunnerPlugin that creates executable OSGi JARs from any .bndrun file.
For any .bndrun file in your project:
./gradlew buildRunner.<name>Examples:
./gradlew buildRunner.goss-core # Uses goss-core.bndrun
./gradlew buildRunner.goss-core-ssl # Uses goss-core-ssl.bndrun
./gradlew buildRunner.my-app # Uses my-app.bndrunCreate a file like my-app.bndrun:
# OSGi Framework
-runfw: org.apache.felix.framework;version='[7.0.5,8)'
-runee: JavaSE-21
# Bundles to include
-runbundles: \
${activemq-runpath},\
${jakarta-runpath},\
${slf4j-runpath},\
pnnl.goss.core.core-api;version=latest,\
pnnl.goss.core.goss-client;version=latest,\
pnnl.goss.core.goss-core-server;version=latest
# Runtime properties
-runproperties: \
activemq.host=0.0.0.0,\
openwire.port=61616,\
stomp.port=61613Then build it:
./gradlew buildRunner.my-app
java -jar pnnl.goss.core.runner/generated/runners/my-app-runner.jarThe plugin is available in buildSrc/ and can be used in other projects:
1. Copy buildSrc to your project:
cp -r GOSS/buildSrc /path/to/your/project/2. Apply the plugin in your build.gradle:
apply plugin: com.pnnl.goss.gradle.BndRunnerPlugin
bndRunner {
bundleDirs = [
file('generated'),
file('../GOSS/pnnl.goss.core/generated') // Include GOSS bundles
]
configDir = file('conf')
}3. Use it:
cd /path/to/your/project
./gradlew buildRunner.my-runtimeThe Java client now supports both Queue and Topic destination types, matching the Python client's behavior:
import pnnl.goss.core.Client.DESTINATION_TYPE;
// Subscribe to a queue (point-to-point, for request/response patterns)
client.subscribe("goss.gridappsd.process.request", handler, DESTINATION_TYPE.QUEUE);
// Subscribe to a topic (pub/sub, for broadcast events)
client.subscribe("goss.gridappsd.simulation.output.123", handler, DESTINATION_TYPE.TOPIC);
// Publish to a queue
client.publish("goss.gridappsd.process.request", message, DESTINATION_TYPE.QUEUE);
// Publish to a topic
client.publish("goss.gridappsd.platform.log", message, DESTINATION_TYPE.TOPIC);
// Send request and get response (defaults to QUEUE to match Python)
client.getResponse(request, "goss.gridappsd.process.request", RESPONSE_FORMAT.JSON);
// Send request with explicit destination type
client.getResponse(request, "my.topic", RESPONSE_FORMAT.JSON, DESTINATION_TYPE.TOPIC);Key differences:
| Destination | Publishing Behavior | Subscribing Behavior |
|---|---|---|
| QUEUE | Message delivered to one consumer. If no consumers, message is stored until one connects. | Only one subscriber receives each message (load balancing). |
| TOPIC | Message delivered to all active subscribers. If no subscribers, message is lost. | All subscribers receive a copy of each message (broadcast). |
Default behaviors:
getResponse()defaults to QUEUE (matches Python client, ensures request reaches the handler)subscribe()defaults to TOPIC (typical for event streaming)publish(destination, message)defaults to TOPIC (for backward compatibility)
A new CLI tool for subscribing and publishing to GOSS queues/topics:
# Build the CLI
./gradlew :pnnl.goss.core.runner:createCli
# Subscribe to a queue
java -jar pnnl.goss.core.runner/generated/executable/goss-cli.jar subscribe --queue goss.gridappsd.process.request
# Subscribe to a topic
java -jar pnnl.goss.core.runner/generated/executable/goss-cli.jar sub --topic goss.gridappsd.simulation.output.123
# Publish to a queue (default)
java -jar pnnl.goss.core.runner/generated/executable/goss-cli.jar publish goss.gridappsd.process.request '{"type":"query"}'
# Publish to a topic
java -jar pnnl.goss.core.runner/generated/executable/goss-cli.jar pub --topic goss.gridappsd.platform.log 'Test message'
# With authentication and custom broker
java -jar pnnl.goss.core.runner/generated/executable/goss-cli.jar sub -b tcp://activemq:61616 -u admin -p admin -q my.queueOptions:
-t, --topic- Use a topic (default for subscribe)-q, --queue- Use a queue (default for publish)-b, --broker URL- Broker URL (default: tcp://localhost:61616)-u, --user USER- Username for authentication-p, --password PW- Password for authentication-h, --help- Show help message
# Terminal 1 - Start first subscriber
$ java -jar goss-cli.jar sub --topic events
GOSS Subscriber
===============
Broker: tcp://localhost:61616
Destination: events
Type: TOPIC
Connected! Waiting for messages... (Ctrl+C to stop)
# Terminal 2 - Start second subscriber
$ java -jar goss-cli.jar sub --topic events
Connected! Waiting for messages... (Ctrl+C to stop)
# Terminal 3 - Publish a message
$ java -jar goss-cli.jar pub --topic events "Hello everyone!"
Message published successfully!
# Result: BOTH Terminal 1 AND Terminal 2 receive:
--- Message Received ---
Hello everyone!
------------------------# Terminal 1 - Start first consumer
$ java -jar goss-cli.jar sub --queue tasks
GOSS Subscriber
===============
Broker: tcp://localhost:61616
Destination: tasks
Type: QUEUE
Connected! Waiting for messages... (Ctrl+C to stop)
# Terminal 2 - Start second consumer
$ java -jar goss-cli.jar sub --queue tasks
Connected! Waiting for messages... (Ctrl+C to stop)
# Terminal 3 - Publish messages
$ java -jar goss-cli.jar pub --queue tasks "Task 1"
$ java -jar goss-cli.jar pub --queue tasks "Task 2"
# Result: Terminal 1 receives "Task 1", Terminal 2 receives "Task 2" (load balanced)
# Each message goes to only ONE consumer
# Queue persistence - messages wait for consumers:
$ java -jar goss-cli.jar pub --queue waiting "I'll wait here"
# (no subscribers running - message is stored)
# Later, start a subscriber:
$ java -jar goss-cli.jar sub --queue waiting
--- Message Received ---
I'll wait here
------------------------
# Message was stored and delivered when consumer connected!GOSS now includes optional JWT (JSON Web Token) authentication support:
// Create client with token authentication
ClientFactory factory = // ... get factory
Client client = factory.create(PROTOCOL.OPENWIRE, credentials, true); // useToken=trueNew Security Classes:
JWTAuthenticationToken- Token data structure and parsingSecurityConfig- Token validation and creation interfaceGossSecurityManager- Enhanced security managementRoleManager- Role-based permission management
Security Configuration:
goss.system.use.token=true
goss.system.token.secret=your-secret-key
goss.system.manager=admin
goss.system.manager.password=admin-passwordClients now automatically renew their JMS session when publish operations fail, improving reliability in long-running applications.
GOSS uses Semantic Versioning with automated API change detection:
| Change Type | Version Bump | Example |
|---|---|---|
| MAJOR | X.0.0 | Interface changes, removed public methods, breaking changes |
| MINOR | x.Y.0 | New public methods on classes, new classes (backward compatible) |
| PATCH | x.y.Z | Implementation-only changes, bug fixes |
make version # Show versions of all bundles
make build # Build all bundles
make test # Run tests
make clean # Clean build artifactsBefore bumping versions, analyze your changes to determine the appropriate version bump:
make check-api # Analyze API changes and get recommendationExample output:
API Change Analysis
============================================================
pnnl.goss.core.core-api
MAJOR changes detected:
- Interface method removed: public abstract void publish(javax.jms.Destination, ...)
- Interface method added: public abstract void publish(jakarta.jms.Destination, ...)
pnnl.goss.core.goss-client
MINOR changes detected:
- Public method added: public void reconnect()
pnnl.goss.core.goss-core-commands
No API changes
============================================================
Recommended Version Bump:
MAJOR - Breaking API changes detected
Run: make bump-major
# Automatic version bumping (reads current version, increments appropriately)
make bump-major # 11.0.0 -> 12.0.0-SNAPSHOT (breaking changes)
make bump-minor # 11.0.0 -> 11.1.0-SNAPSHOT (new features)
make bump-patch # 11.0.0 -> 11.0.1-SNAPSHOT (bug fixes)
make next-snapshot # Same as bump-patch (use after release)
# Manual version setting
make release VERSION=11.0.0 # Set exact release version (removes -SNAPSHOT)
make snapshot VERSION=11.1.0 # Set exact snapshot version (adds -SNAPSHOT)# 1. Analyze changes to determine version bump type
make check-api
# 2. If currently on snapshot, set release version
make version # Verify: 11.0.0-SNAPSHOT
make release VERSION=11.0.0 # Changes to: 11.0.0
# 3. Build, test, and push release
make build && make test
make push-release # Push to ../GOSS-Repository/release/
# 4. Tag and commit release
git add -A && git commit -m "Release 11.0.0"
git tag v11.0.0
git push && git push --tags
# 5. Start next development cycle
make next-snapshot # Bumps to: 11.0.1-SNAPSHOT
git add -A && git commit -m "Start 11.0.1-SNAPSHOT development"
git pushGOSS bundles can be published to a local GOSS-Repository clone for OSGi resolution:
# Push snapshot JARs to ../GOSS-Repository/snapshot/
make push-snapshot
# Push release JARs to ../GOSS-Repository/release/
make push-releaseNote: The GOSS-Repository must be cloned as a sibling directory (../GOSS-Repository). This is the local repository used for BND workspace resolution, not a remote Maven repository.
When making changes to GOSS, follow these guidelines:
MAJOR version bump required:
- Adding or removing methods from an interface (breaks implementors)
- Removing public methods from a class
- Changing method signatures (parameters, return types)
- Changing class hierarchy (superclass, implemented interfaces)
MINOR version bump required:
- Adding new public methods to a class (not interface)
- Adding new classes
- Adding new packages
PATCH version bump required:
- Bug fixes with no API changes
- Performance improvements
- Internal refactoring
- Documentation updates
- Quick Start Guide - Get up and running with GOSS in 5 minutes
- Developer Setup - Complete development environment setup for Eclipse and VS Code
- Production Deployment - Production deployment guide with systemd, SSL, and monitoring
- Code Formatting Guide - Code style and formatting configuration for consistent code across IDEs
- Documentation Index - Complete documentation hub
- Issue Tracker - Report bugs or request features
Ubuntu/Debian:
sudo apt update
sudo apt install openjdk-21-jdk
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64CentOS/RHEL/Fedora:
sudo dnf install java-21-openjdk-devel # Fedora
sudo yum install java-21-openjdk-devel # CentOS/RHELmacOS (Homebrew):
brew install openjdk@21
export PATH="/usr/local/opt/openjdk@21/bin:$PATH"Windows: Download from Adoptium or OpenJDK
Using SDKMAN (recommended for development):
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk install java 21.0.5-tem
sdk use java 21.0.5-temBefore (Java EE):
import javax.jms.Connection;
import javax.annotation.PostConstruct;After (Jakarta EE):
import jakarta.jms.Connection;
import jakarta.annotation.PostConstruct;Updated packages:
jakarta.jms:jakarta.jms-api:3.1.0(wasjavax.jms)jakarta.annotation:jakarta.annotation-api:2.1.1jakarta.resource:jakarta.resource-api:2.1.0jakarta.transaction:jakarta.transaction-api:2.0.1jakarta.inject:jakarta.inject-api:2.0.1jakarta.xml.bind:jakarta.xml.bind-api:4.0.2
- ActiveMQ 6.2.0 (was 5.15.x)
- Native Jakarta JMS support
- No more shim/bridge layers
- Updated broker configuration
- Shiro 2.0.0 (was 1.x)
- API changes in authentication/authorization
- Updated security configuration
- Spring Framework 6.2.0 (was 5.x)
- Jackson 2.18.1 (was 2.17.x)
- SLF4J 2.0.16 (was 1.7.x)
- Apache Felix 7.0.5 OSGi framework
- Gradle 8.10 with BND 6.4.0
- Updated to OSGi R8 specifications
- Modular BndRunnerPlugin for creating custom OSGi runners
- Improved bundle dependency resolution
✅ Environment:
- Install JDK 21
- Set
JAVA_HOMEto JDK 21 - Verify:
java -versionshows 21.x
✅ Code Updates (if extending GOSS):
- Replace
javax.jms.*withjakarta.jms.* - Replace other
javax.*EE packages withjakarta.* - Update Shiro security configurations for 2.0 API changes
- Test ActiveMQ connections (configuration may need updates)
✅ Build:
- Update Gradle wrapper if using older version
- Clear Gradle cache:
./gradlew clean - Run tests:
./gradlew check
ActiveMQ Configuration:
- Old broker URLs still work, but new features require updated configuration
- SSL/TLS configuration has changed in ActiveMQ 6.x
Shiro Security:
- Some authentication realm APIs have changed
- Review custom
Realmimplementations
Removed Java EE APIs:
- All
javax.jms,javax.annotation, etc. → Use Jakarta equivalents
GOSS/
├── pnnl.goss.core/ # Core bundles
│ ├── core-api/ # Core API interfaces
│ ├── goss-client/ # Client implementation
│ ├── goss-core-server/ # Server implementation
│ ├── goss-core-server-api/ # Server API interfaces
│ ├── goss-core-security/ # Security integration (Shiro)
│ └── security-propertyfile/ # Property-file authentication
├── pnnl.goss.core.runner/ # Executable runners
│ ├── goss-core.bndrun # OSGi runtime definition
│ └── conf/ # Runtime configuration
├── buildSrc/ # Gradle plugins (BndRunnerPlugin)
├── cnf/ # BND workspace configuration
├── scripts/ # Build and release scripts
├── Makefile # Build automation
└── push-to-local-goss-repository.py # Repository publishing tool
GOSS serves as the messaging foundation for:
- GridAPPS-D - Grid Application Platform for Planning and Simulation with Distribution. GridAPPS-D is built as an OSGi application on top of GOSS, using its messaging framework for simulation orchestration, data management, and application integration.
- Java 21 with modern language features
- OSGi (Apache Felix 7.0.5) for modular service architecture
- BND Tools 6.4.0 for OSGi bundle management
- Apache ActiveMQ 6.2.0 for JMS messaging (Jakarta EE compatible)
- Apache Shiro 2.0 for authentication and authorization
- Gradle 8.10 build system
| Repository | Description |
|---|---|
| GOSS-GridAPPS-D | GridAPPS-D platform built on GOSS |
| GOSS-Repository | OSGi bundle repository for BND resolution |
| gridappsd-docker | Docker deployment for GridAPPS-D |
| gridappsd-python | Python client library |
This project is licensed under the BSD-3-Clause License. See LICENSE for details.
Contributions are welcome! Please submit pull requests to the develop branch.
- Documentation: See the docs/ directory
- Issues: https://github.com/GridOPTICS/GOSS/issues