Skip to content

Commit 3dc6f52

Browse files
ChrisHegartycoffeys
andcommitted
8261160: Add a deserialization JFR event
Co-authored-by: Sean Coffey <[email protected]> Co-authored-by: Chris Hegarty <[email protected]> Reviewed-by: coffeys, rriggs, dfuchs, egahlin
1 parent a305743 commit 3dc6f52

File tree

12 files changed

+615
-22
lines changed

12 files changed

+615
-22
lines changed

‎src/java.base/share/classes/java/io/ObjectInputStream.java‎

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -48,6 +48,7 @@
4848
import static java.io.ObjectStreamClass.processQueue;
4949

5050
import jdk.internal.access.SharedSecrets;
51+
import jdk.internal.event.DeserializationEvent;
5152
import jdk.internal.misc.Unsafe;
5253
import sun.reflect.misc.ReflectUtil;
5354
import sun.security.action.GetBooleanAction;
@@ -1323,21 +1324,25 @@ public final void setObjectInputFilter(ObjectInputFilter filter) {
13231324
}
13241325

13251326
/**
1326-
* Invoke the serialization filter if non-null.
1327+
* Invokes the serialization filter if non-null.
1328+
*
13271329
* If the filter rejects or an exception is thrown, throws InvalidClassException.
13281330
*
1331+
* Logs and/or commits a {@code DeserializationEvent}, if configured.
1332+
*
13291333
* @param clazz the class; may be null
13301334
* @param arrayLength the array length requested; use {@code -1} if not creating an array
13311335
* @throws InvalidClassException if it rejected by the filter or
13321336
* a {@link RuntimeException} is thrown
13331337
*/
13341338
private void filterCheck(Class<?> clazz, int arrayLength)
13351339
throws InvalidClassException {
1340+
// Info about the stream is not available if overridden by subclass, return 0
1341+
long bytesRead = (bin == null) ? 0 : bin.getBytesRead();
1342+
RuntimeException ex = null;
1343+
ObjectInputFilter.Status status = null;
1344+
13361345
if (serialFilter != null) {
1337-
RuntimeException ex = null;
1338-
ObjectInputFilter.Status status;
1339-
// Info about the stream is not available if overridden by subclass, return 0
1340-
long bytesRead = (bin == null) ? 0 : bin.getBytesRead();
13411346
try {
13421347
status = serialFilter.checkInput(new FilterValues(clazz, arrayLength,
13431348
totalObjectRefs, depth, bytesRead));
@@ -1355,12 +1360,24 @@ private void filterCheck(Class<?> clazz, int arrayLength)
13551360
status, clazz, arrayLength, totalObjectRefs, depth, bytesRead,
13561361
Objects.toString(ex, "n/a"));
13571362
}
1358-
if (status == null ||
1359-
status == ObjectInputFilter.Status.REJECTED) {
1360-
InvalidClassException ice = new InvalidClassException("filter status: " + status);
1361-
ice.initCause(ex);
1362-
throw ice;
1363-
}
1363+
}
1364+
DeserializationEvent event = new DeserializationEvent();
1365+
if (event.shouldCommit()) {
1366+
event.filterConfigured = serialFilter != null;
1367+
event.filterStatus = status != null ? status.name() : null;
1368+
event.type = clazz;
1369+
event.arrayLength = arrayLength;
1370+
event.objectReferences = totalObjectRefs;
1371+
event.depth = depth;
1372+
event.bytesRead = bytesRead;
1373+
event.exceptionType = ex != null ? ex.getClass() : null;
1374+
event.exceptionMessage = ex != null ? ex.getMessage() : null;
1375+
event.commit();
1376+
}
1377+
if (serialFilter != null && (status == null || status == ObjectInputFilter.Status.REJECTED)) {
1378+
InvalidClassException ice = new InvalidClassException("filter status: " + status);
1379+
ice.initCause(ex);
1380+
throw ice;
13641381
}
13651382
}
13661383

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package jdk.internal.event;
27+
28+
/**
29+
* Event details relating to deserialization.
30+
*/
31+
32+
public final class DeserializationEvent extends Event {
33+
public boolean filterConfigured;
34+
public String filterStatus;
35+
public Class<?> type;
36+
public int arrayLength;
37+
public long objectReferences;
38+
public long depth;
39+
public long bytesRead;
40+
public Class<?> exceptionType;
41+
public String exceptionMessage;
42+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package jdk.jfr.events;
27+
28+
import jdk.jfr.Category;
29+
import jdk.jfr.Description;
30+
import jdk.jfr.Label;
31+
import jdk.jfr.Name;
32+
import jdk.jfr.internal.MirrorEvent;
33+
34+
@Category({"Java Development Kit", "Serialization"})
35+
@Label("Deserialization")
36+
@Name("jdk.Deserialization")
37+
@Description("Results of deserialiation and ObjectInputFilter checks")
38+
@MirrorEvent(className = "jdk.internal.event.DeserializationEvent")
39+
public final class DeserializationEvent extends AbstractJDKEvent {
40+
41+
@Label("Filter Configured")
42+
public boolean filterConfigured;
43+
44+
@Label("Filter Status")
45+
public String filterStatus;
46+
47+
@Label ("Type")
48+
public Class<?> type;
49+
50+
@Label ("Array Length")
51+
public int arrayLength;
52+
53+
@Label ("Object References")
54+
public long objectReferences;
55+
56+
@Label ("Depth")
57+
public long depth;
58+
59+
@Label ("Bytes Read")
60+
public long bytesRead;
61+
62+
@Label ("Exception Type")
63+
public Class<?> exceptionType;
64+
65+
@Label ("Exception Message")
66+
public String exceptionMessage;
67+
}

‎src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/JDKEvents.java‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -38,6 +38,7 @@
3838
import jdk.jfr.events.FileForceEvent;
3939
import jdk.jfr.events.FileReadEvent;
4040
import jdk.jfr.events.FileWriteEvent;
41+
import jdk.jfr.events.DeserializationEvent;
4142
import jdk.jfr.events.ProcessStartEvent;
4243
import jdk.jfr.events.SecurityPropertyModificationEvent;
4344
import jdk.jfr.events.SocketReadEvent;
@@ -55,11 +56,12 @@
5556
public final class JDKEvents {
5657

5758
private static final Class<?>[] mirrorEventClasses = {
59+
DeserializationEvent.class,
60+
ProcessStartEvent.class,
5861
SecurityPropertyModificationEvent.class,
5962
TLSHandshakeEvent.class,
6063
X509CertificateEvent.class,
61-
X509ValidationEvent.class,
62-
ProcessStartEvent.class
64+
X509ValidationEvent.class
6365
};
6466

6567
private static final Class<?>[] eventClasses = {
@@ -73,11 +75,13 @@ public final class JDKEvents {
7375
ErrorThrownEvent.class,
7476
ActiveSettingEvent.class,
7577
ActiveRecordingEvent.class,
78+
jdk.internal.event.DeserializationEvent.class,
79+
jdk.internal.event.ProcessStartEvent.class,
7680
jdk.internal.event.SecurityPropertyModificationEvent.class,
7781
jdk.internal.event.TLSHandshakeEvent.class,
7882
jdk.internal.event.X509CertificateEvent.class,
7983
jdk.internal.event.X509ValidationEvent.class,
80-
jdk.internal.event.ProcessStartEvent.class,
84+
8185
DirectBufferStatisticsEvent.class
8286
};
8387

‎src/jdk.jfr/share/conf/jfr/default.jfc‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,11 @@
665665
<setting name="threshold" control="socket-io-threshold">20 ms</setting>
666666
</event>
667667

668+
<event name="jdk.Deserialization">
669+
<setting name="enabled">false</setting>
670+
<setting name="stackTrace">true</setting>
671+
</event>
672+
668673
<event name="jdk.SecurityPropertyModification">
669674
<setting name="enabled">false</setting>
670675
<setting name="stackTrace">true</setting>

‎src/jdk.jfr/share/conf/jfr/profile.jfc‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,11 @@
665665
<setting name="threshold" control="socket-io-threshold">10 ms</setting>
666666
</event>
667667

668+
<event name="jdk.Deserialization">
669+
<setting name="enabled">false</setting>
670+
<setting name="stackTrace">true</setting>
671+
</event>
672+
668673
<event name="jdk.SecurityPropertyModification">
669674
<setting name="enabled">false</setting>
670675
<setting name="stackTrace">true</setting>

‎test/jdk/java/io/Serializable/serialFilter/GlobalFilterTest.java‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -53,6 +53,18 @@
5353
*
5454
* @summary Test Global Filters
5555
*/
56+
57+
/* @test
58+
* @bug 8261160
59+
* @summary Add a deserialization JFR event
60+
* @build GlobalFilterTest SerialFilterTest
61+
* @requires vm.hasJFR
62+
* @run testng/othervm/policy=security.policy
63+
* -XX:StartFlightRecording=name=DeserializationEvent,dumponexit=true
64+
* -Djava.security.properties=${test.src}/java.security-extra1
65+
* -Djava.security.debug=properties GlobalFilterTest
66+
*/
67+
5668
@Test
5769
public class GlobalFilterTest {
5870
private static final String serialPropName = "jdk.serialFilter";

0 commit comments

Comments
 (0)