Overview: S7-300 Data to a Java Application via OPC UA
The Siemens S7-300 CPU family has no native OPC UA server. To expose S7-300 tags to a Java client you must run a Windows-based PC with SIMATIC NET, which acts as the OPC UA server and bridges an S7 connection (Industrial Ethernet, PROFIBUS, or MPI) to a standards-based opc.tcp:// endpoint. A Java application then consumes that endpoint using the official OPC Foundation Java stack or a third-party Java SDK such as Eclipse Milo or Prosys OPC UA.
This reference covers the full integration for a process-data scenario (e.g., methane concentration logging) where the Java client must read measured values from the S7-300 and write them to a time-stamped archive. The configuration is identical whether the Java client is a desktop application, a Tomcat servlet, or a Spring Boot microservice, and the OPC UA protocol guarantees that the same client code runs unchanged when the controller is later upgraded to an S7-1200 or S7-1500 with its built-in OPC UA server.
OPC UA Data Flow and S7-300 Architecture
The end-to-end path of one measured value (e.g., methane concentration) is:
-
S7-300 CPU — holds the process tag. Typical items:
DB100.DBD0(REAL, methane % LEL),DB100.DBW4(INT, status),DB100.DBX6.0(BOOL, alarm). - CP 343-1 / CP 343-1 Advanced — communications processor that provides the Industrial Ethernet port on the S7-300 rack.
- SIMATIC NET PC software — on a Windows host, runs both the S7 connection (named "S7 connection" in STEP 7 / NCM PC) and the OPC UA Server.
-
OPC UA endpoint — listens on
opc.tcp://<simatic-net-host>:4840with the configured SecurityPolicy and authentication mode. - Java OPC UA client — opens a session, browses the AddressSpace, and subscribes to selected monitored items.
- The Java client applies an application-level time-stamp at the moment the notification is consumed, independent of the source controller.
Prerequisites: Hardware, Software, and Licensing
| Component | Requirement |
|---|---|
| S7-300 CPU | CPU 31x with an Ethernet CP (CPU 315-2 PN/DP, CPU 317-2 PN/DP, etc.) and a CP 343-1 or onboard PROFINET port |
| STEP 7 / TIA Portal project | DBs configured for the methane tag and control flags; tags must be reachable as absolute addresses |
| PC hardware | Windows 10/11 or Windows Server 2016/2019/2022, x64, 4 GB RAM minimum, 100 Mbit/s Ethernet |
| SIMATIC NET | Version with OPC UA Server for S7 connections. The OPC UA server for S7 connections is available as of the CD2800 release of SIMATIC NET, per Siemens support entry 31675909. |
| SIMATIC NET license | OPC UA Server license key for the S7 connection count you are activating |
| Java JDK | JDK 11 or newer (LTS); JDK 17 and JDK 21 are validated against Eclipse Milo 0.6.x |
| Java OPC UA SDK | Eclipse Milo (open source), Prosys OPC UA Java SDK (commercial), or OPC Foundation Java stack (commercial / RCL) |
| Network | TCP 4840 reachable from the Java host to the SIMATIC NET host; TCP 102 (ISO-on-TCP / RFC 1006) reachable from SIMATIC NET to the S7-300 CP |
| Firewall | Allow inbound 4840/tcp to the SIMATIC NET service; allow inbound 102/tcp to the S7-300 CP |
Install SIMATIC NET before plugging in the S7 connection; the S7-OPC server components and license plug-in only become visible in the PC station hardware catalog after the main install completes.
Configuring the SIMATIC NET OPC UA Server for S7 Connections
Configuration lives in the SIMATIC Manager (STEP 7 V5.x) or TIA Portal project that targets the PC station. The PC station must contain a virtual "OPC Server" application and an S7 connection to the S7-300.
- Open the PC station hardware configuration and insert an "OPC Server" application on the virtual PC.
- Configure an S7 connection from the OPC Server to the S7-300 CP. The connection partner is the S7-300 IP address and the S7 connection ID defined in the CP's STEP 7 configuration. The connection type "S7 connection" must match on both sides.
- Define the S7 symbols to expose. Each absolute address or symbolic name becomes a UA variable. For the methane application, expose at minimum:
-
DB100.DBD0— REAL, methane concentration -
DB100.DBW4— INT, status word -
DB100.DBX6.0— BOOL, alarm flag
-
- Compile and load the PC station configuration to the runtime system. The S7 communication service and the OPC UA server start automatically under the local system account.
- Open the SIMATIC NET "Commissioning" tool, browse to the OPC UA Server settings, and set the SecurityPolicy of the endpoint. For an isolated plant network you can start with
None+ anonymous authentication; for production useBasic256Sha256+ user/password or certificate-based client auth. - Confirm the endpoint answers a
GetEndpointsrequest from any external OPC UA browser.
Full procedural and parameter documentation is in the SIMATIC NET programming manual referenced by Siemens support entry 42783968 (page 116 of the cited edition lists the language bindings for the UA interface) and the SIMATIC NET OPC UA Server for S7 connections entry at 31675909.
Choosing a Java OPC UA Client SDK
The OPC Foundation defines language-agnostic bindings for OPC UA in C, .NET (C#, VB.NET), Java, and C++, and the corresponding communication stacks are distributed by the Foundation. The Java stack is one of the four official bindings and is the path of least resistance for a Java application.
| SDK | License | Java version | Strengths | Limits |
|---|---|---|---|---|
| OPC Foundation Java Stack (reference implementation) | OPC Foundation commercial / RCL | JDK 8+ | Authoritative, used by OPC Foundation tools and test harnesses | Commercial license for production deployment; heavier API |
| Eclipse Milo | EPL-2.0 (open source) | JDK 11+ | Active community, idiomatic async API, Spring Boot samples | Not OPC Foundation compliance certified |
| Prosys OPC UA Java SDK | Commercial, free for development | JDK 8+ | Long-term support, certified, has SIMATIC NET sample code | Paid for production runtime |
For a lab or pilot deployment Eclipse Milo is the lowest-friction option. For a regulated plant deployment (GAMP, 21 CFR Part 11, IEC 62443) select Prosys or the OPC Foundation commercial stack, both of which hold OPC Foundation compliance certification.
Java Client Implementation with Eclipse Milo
Add the Milo dependencies to a Maven project:
<dependency>
<groupId>org.eclipse.milo</groupId>
<artifactId>sdk-client</artifactId>
<version>0.6.9</version>
</dependency>
<dependency>
<groupId>org.eclipse.milo</groupId>
<artifactId>binaryserver</artifactId>
<version>0.6.9</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.13</version>
</dependency>
Minimum code to discover the endpoints, open a session, read a value, and close cleanly:
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
public class S7OpcUaReader {
public static void main(String[] args) throws Exception {
String endpointUrl = "opc.tcp://10.0.0.50:4840";
OpcUaClient client = OpcUaClient.create(
endpointUrl,
endpoints -> endpoints.stream()
.filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getUri()))
.findFirst(),
configBuilder -> configBuilder
.setApplicationName(LocalizedText.english("Java UA Client"))
.setApplicationUri("urn:java:opcua:client")
.setRequestTimeout(uint(5000))
);
client.connect().get();
// SIMATIC NET exposes S7 tags under its own numeric namespace, typically ns=2 or ns=4.
NodeId methaneConcentration = new NodeId(2, "DB100.DBD0");
DataValue dv = client
.readValue(0.0, TimestampsToReturn.Both, methaneConcentration)
.get();
System.out.println("Value : " + dv.getValue().getValue());
System.out.println("Source time : " + dv.getSourceTime().getJavaDate());
System.out.println("Server time : " + dv.getServerTime().getJavaDate());
client.disconnect().get();
}
}
The same logic in the OPC Foundation Java stack uses the UaClient SDK and an SessionActivationHelper:
import org.opcfoundation.ua.client.UaClient;
import org.opcfoundation.ua.core.ReadParameters;
UaClient client = new UaClient("opc.tcp://10.0.0.50:4840");
client.connect();
ReadParameters rp = new ReadParameters();
rp.getNodesToRead().add(new ReadValueId(
new NodeId(2, "DB100.DBD0"), AttributeId.Value, null, QualifiedName.NULL));
DataValue[] results = client.Read(rp);
System.out.println("CH4: " + results[0].getValue().getValue());
Building a Time-Stamped Data Logger with Subscriptions
For continuous logging, use a UA Subscription with monitored items instead of polling readValue. The server pushes changed values; the client records its own time-stamp the moment a notification arrives. This decouples the logging rate from the polling rate and survives temporary network outages with the server's PublishingInterval and KeepAliveCount acting as a buffer.
import org.eclipse.milo.opcua.sdk.client.subscriptions.ManagedSubscription;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.time.Instant;
import java.util.List;
ManagedSubscription sub = client
.getSubscriptionManager()
.createSubscription(250.0) // publishingInterval ms
.get();
NodeId ch4 = new NodeId(2, "DB100.DBD0");
NodeId alarm = new NodeId(2, "DB100.DBX6.0";)
sub.addDataItems(List.of(ch4, alarm)).get();
sub.addDataItemsListener((items, values) -> {
Instant tClient = Instant.now();
try (BufferedWriter w = new BufferedWriter(
new FileWriter("methane.csv", true))) {
for (int i = 0; i < items.size(); i++) {
String tag = items.get(i).getNodeId().getIdentifier().toString();
Object val = values.get(i).getValue().getValue();
w.write(tClient + "," + tag + "," + val + "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
});
Recommended parameters when calling createSubscription(double publishingInterval):
| Parameter | Typical value | Effect |
|---|---|---|
| publishingInterval | 250 ms | How often the server checks monitored items for change |
| samplingInterval | 0 (server decides) or 100 ms | Source sampling on the SIMATIC NET server side |
| queueSize | 10 | How many samples are buffered if the client is slow |
| discardOldest | true | When the queue is full, drop oldest to keep latency low |
| KeepAliveCount | 10 | Number of empty publish cycles before the server sends a keep-alive |
| LifeTimeCount | 3 × KeepAliveCount | Server terminates the subscription if no publish is acknowledged |
Security Policies, Certificates, and Authentication
SIMATIC NET's OPC UA server supports the SecurityPolicies defined by the OPC UA specification. The choice of policy is made in the SIMATIC NET Commissioning tool and must match on the client.
| SecurityPolicy | MessageSecurityMode | Use case |
|---|---|---|
| None | Invalid / None | Lab, isolated VLAN, commissioning only |
| Basic128Rsa15 | Sign / SignAndEncrypt | Legacy systems; considered weak by modern standards |
| Basic256Sha256 | Sign / SignAndEncrypt | Production deployments with SHA-2 trust chain |
| Aes128Sha256RsaOaep | Sign / SignAndEncrypt | Highest available in SIMATIC NET, preferred for new plants |
To enable a non-None policy on the Java side, install the SIMATIC NET server certificate into the Java truststore:
keytool -importcert -alias simatic-net \
-file simatic-net-server.der \
-keystore $JAVA_HOME/lib/security/cacerts \
-storepass changeit
For two-way authentication, export the Java client's certificate and import it into the SIMATIC NET trusted clients list. The OPC Foundation Java stack stores its client certificate in PKI/own/certs inside the application folder; Eclipse Milo defaults to ~/.milo/client.pfx.
DataValue source time is null and only the application time-stamp is meaningful. Switch on the TimestampsToReturn.Both flag in the read or the subscription to retrieve the source time-stamp from the SIMATIC NET server.Java vs VB.NET OPC UA Client Comparison
The Java and .NET bindings of OPC UA expose the same concepts (Session, Subscription, MonitoredItem, DataValue) and the same binary protocol on the wire. The differences are at the language-idiom level, not in the protocol.
| Aspect | VB.NET (.NET) | Java |
|---|---|---|
| SDK | OPC Foundation .NET Standard stack, also wrapped by SIMATIC NET examples | OPC Foundation Java stack, Eclipse Milo, Prosys |
| Async model | async/await on Task<T>
|
CompletableFuture, Reactive Streams, or callbacks |
| Project setup | NuGet packages, Visual Studio project file | Maven or Gradle; any IDE |
| Deployment OS | Windows-centric for .NET Framework 4.x; .NET 6+ is cross-platform | OS-neutral; runs on Linux servers, edge gateways, Android |
| Containerization | Possible with .NET 6+; larger image footprint | Native fit for Docker, slim JRE base images (alpine) |
| IDE / debugging | Step into UA stack from Visual Studio | Step into UA stack from IntelliJ, Eclipse, or VS Code |
| Typical use case | Windows-only HMI extension, WPF / WinForms front-end | Linux service, REST gateway, Kafka producer, time-series pipeline |
If your application must run on a Linux server, an Android tablet, or inside a Docker container, the Java binding is the better fit. If the application is a Windows-only HMI extension written in WPF or WinForms and you need to bind the UA events into UI components, the .NET stack has tighter tooling. The two bindings can also be mixed: a Java back-end reads from SIMATIC NET and a VB.NET front-end consumes the back-end over REST, MQTT, or WebSocket.
Verification, Acceptance Test, and Troubleshooting
Use the following acceptance procedure before handing the integration over to operations:
- From the Java host, open any OPC UA browser (for example, the free Prosys OPC UA Browser) and call
GetEndpointsonopc.tcp://<simatic-net-host>:4840. Confirm at least oneNoneorBasic256Sha256endpoint is returned. - Browse the UA AddressSpace. The S7 tags should appear under the SIMATIC NET default namespace (typically
ns=2orns=4depending on the project version). - Read a known static value stored in
DB100.DBD0from the S7-300 program and verify it matches what STEP 7 online shows for the same DB. - Force a value change in the S7-300 with a watch table and confirm the Java subscription receives a notification within the configured
publishingInterval. - Inspect the source and server time-stamps of the received
DataValue. The server time must be monotonically increasing; large gaps indicate the SIMATIC NET host is overloaded or the S7 connection is being throttled. - Disconnect and reconnect the Java client to verify session recovery and automatic re-subscription of monitored items.
| Symptom | Likely cause | Fix |
|---|---|---|
Java client cannot reach opc.tcp://host:4840
|
Windows Firewall on the SIMATIC NET host blocking inbound 4840 | Add an inbound rule for 4840/tcp to scsas.exe / SIMATIC NET service; on Linux clients open the Java host outbound 4840/tcp |
Endpoints visible but session returns Bad_SecurityChecksFailed
|
Mismatched SecurityPolicy or MessageSecurityMode | Match SecurityPolicy (None, Basic256Sha256, etc.) and MessageSecurityMode.Sign or SignAndEncrypt on both sides |
Bad_NodeIdUnknown on a tag |
The S7 symbol was not added to the OPC Server's symbol table or DB number is wrong | Re-export the S7 symbols in the SIMATIC NET configuration; verify the absolute address in the S7-300 program |
| Values update slowly (multi-second) | Sampling interval on SIMATIC NET set too high, or S7 connection is being throttled by the CP | Reduce the samplingInterval on the monitored item; check CP 343-1 connection resources; reduce publishingInterval
|
| Connection drops every few minutes | KeepAliveCount exceeded; the SIMATIC NET service is being stopped by a Windows service manager or a domain policy | Verify the SIMATIC NET service is set to Automatic and not killed by a watchdog; raise KeepAliveCount and LifeTimeCount
|
| Java client works in Eclipse / IntelliJ but fails from a packaged JAR | Bouncy Castle or Milo native dependencies missing from the classpath; SPI service files not merged | Build a fat-jar with the Maven Shade plugin; verify META-INF/services files for Milo, Bouncy Castle, and Netty are included |
Bad_CommunicationError after working for hours |
SIMATIC NET PC lost the S7 connection to the S7-300 CP | Check CP 343-1 link LEDs, the S7 connection status in the SIMATIC NET Commissioning tool, and any switch port errors between the PC and the CP |
Field-Proven Caveats
- The OPC UA server in SIMATIC NET only becomes available from the CD2800 build onwards for S7 connections, per Siemens support entry 31675909. Older installations must be upgraded before they can serve UA to a Java client.
- The S7-300 cannot be replaced by an S7-1200 / S7-1500 in the same SIMATIC NET project — the PC station is still required for older CPUs even when the rest of the plant is on newer controllers. The cleanest path is a separate PC station for each controller family.
- Eclipse Milo is a community project, not OPC Foundation certified. For SIL / safety-related or audit-controlled deployments select a certified SDK (Prosys or OPC Foundation commercial stack).
- The OPC Foundation Java stack is in long-term maintenance, so Eclipse Milo and Prosys are the realistic long-term Java options.
- Always time-stamp the application value with
Instant.now()at the notification handler, not just at the file write. Notifications can queue inside the server and arrive in bursts; the application time-stamp at the moment of consumption is what regulatory archives expect. - For long-running logging, log a session ID and subscription ID so a restart can re-attach to existing monitored items rather than recreating the entire AddressSpace browse.
Frequently Asked Questions
Can an S7-300 expose OPC UA directly without a PC?
No. The S7-300 CPU family has no built-in OPC UA server. You need a Windows PC running SIMATIC NET as the OPC UA server and an S7 connection to the controller. Only the S7-1200 and S7-1500 families have a native OPC UA server, as documented in the TIA Portal V20 OPC UA guide.
Which Java library should I use for an OPC UA client?
For a non-regulated application Eclipse Milo is the most widely deployed open-source Java SDK (EPL-2.0 license). For a regulated or audit-controlled environment use the Prosys OPC UA Java SDK or the commercial OPC Foundation Java stack, both of which hold OPC Foundation compliance certification.
Does the Java client need a SIMATIC NET license?
No. The SIMATIC NET license is on the server side (the PC running the OPC UA Server). The Java client only needs the OPC UA Java SDK, which is either open source (Eclipse Milo) or commercially licensed to the application vendor, not to the customer deploying it.
How do I time-stamp the measured value in Java?
Either use the source time-stamp on the DataValue returned by a subscription notification, or stamp the value with Instant.now() the moment the notification handler fires. The latter is the application time-stamp and is what most process-data archives require for compliance.
Does the Java code change when I migrate from S7-300 to S7-1500?
The Java client code does not change at all. Only the server endpoint URL and (optionally) the SecurityPolicy change. The S7-1500 with a built-in OPC UA server replaces the SIMATIC NET PC entirely, so you repoint the client to opc.tcp://<s7-1500-cpu-ip>:4840 and the same Milo / OPC Foundation client code reads the same NodeIds.
Is the Java code different from the VB.NET sample in the SIMATIC NET manual?
No — the OPC UA protocol is identical. The Java and VB.NET bindings differ only in async style (CompletableFuture vs async/await) and project tooling (Maven vs NuGet). The session, subscription, monitored item, and DataValue objects map one-to-one between the two stacks.