3434import javax .management .MBeanOperationInfo ;
3535import javax .management .MalformedObjectNameException ;
3636import javax .management .ObjectName ;
37+ import org .jspecify .annotations .NullMarked ;
38+ import org .jspecify .annotations .Nullable ;
3739
40+ @ NullMarked
3841public class MBean implements DynamicMBean {
3942
4043 private static final Logger LOG = Logger .getLogger (MBean .class .getName ());
@@ -47,17 +50,18 @@ public class MBean implements DynamicMBean {
4750 private static class AttributeInfo {
4851 final String name ;
4952 final String description ;
50- final Method getter ;
51- final Method setter ;
53+ final @ Nullable Method getter ;
54+ final @ Nullable Method setter ;
5255
53- AttributeInfo (String name , String description , Method getter , Method setter ) {
56+ AttributeInfo (
57+ String name , String description , @ Nullable Method getter , @ Nullable Method setter ) {
5458 this .name = name ;
5559 this .description = description ;
5660 this .getter = getter ;
5761 this .setter = setter ;
5862 }
5963
60- MBeanAttributeInfo getMBeanAttributeInfo () {
64+ @ Nullable MBeanAttributeInfo getMBeanAttributeInfo () {
6165 try {
6266 return new MBeanAttributeInfo (name , description , getter , setter );
6367 } catch (IntrospectionException e ) {
@@ -116,7 +120,7 @@ private void collectAttributeInfo(Object bean) {
116120 .forEach (ai -> attributeMap .put (ai .name , ai ));
117121 }
118122
119- private AttributeInfo getAttributeInfo (Method m ) {
123+ private @ Nullable AttributeInfo getAttributeInfo (Method m ) {
120124 ManagedAttribute ma = m .getAnnotation (ManagedAttribute .class );
121125 if (ma == null ) {
122126 return null ;
@@ -130,7 +134,7 @@ private AttributeInfo getAttributeInfo(Method m) {
130134 }
131135 }
132136
133- private Method findGetter (Method annotatedMethod ) {
137+ private @ Nullable Method findGetter (Method annotatedMethod ) {
134138 ManagedAttribute ma = annotatedMethod .getAnnotation (ManagedAttribute .class );
135139 try {
136140 if (!"" .equals (ma .getter ())) {
@@ -151,7 +155,7 @@ private Method findGetter(Method annotatedMethod) {
151155 }
152156 }
153157
154- private Method findSetter (Method annotatedMethod ) {
158+ private @ Nullable Method findSetter (Method annotatedMethod ) {
155159 ManagedAttribute ma = annotatedMethod .getAnnotation (ManagedAttribute .class );
156160 if (!"" .equals (ma .setter ())) {
157161 return findMethod (annotatedMethod .getDeclaringClass (), ma .setter ());
@@ -170,7 +174,7 @@ private Method findSetter(Method annotatedMethod) {
170174 return null ;
171175 }
172176
173- private Method findMethod (Class <?> cls , String name ) {
177+ private @ Nullable Method findMethod (Class <?> cls , String name ) {
174178 return Stream .of (cls .getMethods ())
175179 .filter (m -> m .getName ().equals (name ))
176180 .findFirst ()
@@ -184,7 +188,7 @@ private void collectOperationInfo(Object bean) {
184188 .forEach (oi -> operationMap .put (oi .name , oi ));
185189 }
186190
187- private OperationInfo getOperationInfo (Method m ) {
191+ private @ Nullable OperationInfo getOperationInfo (Method m ) {
188192 ManagedOperation mo = m .getAnnotation (ManagedOperation .class );
189193 if (mo == null ) {
190194 return null ;
@@ -214,9 +218,13 @@ private ObjectName generateObjectName(Object bean) {
214218 }
215219
216220 @ Override
217- public Object getAttribute (String attribute ) {
221+ public @ Nullable Object getAttribute (String attribute ) {
218222 try {
219- Object res = attributeMap .get (attribute ).getter .invoke (bean );
223+ AttributeInfo attributeInfo = attributeMap .get (attribute );
224+ if (attributeInfo == null || attributeInfo .getter == null ) {
225+ return null ;
226+ }
227+ Object res = attributeInfo .getter .invoke (bean );
220228 if (res instanceof Map <?, ?>) {
221229 return ((Map <?, ?>) res )
222230 .entrySet ().stream ()
@@ -235,7 +243,11 @@ public Object getAttribute(String attribute) {
235243 @ Override
236244 public void setAttribute (Attribute attribute ) {
237245 try {
238- attributeMap .get (attribute .getName ()).setter .invoke (bean , attribute .getValue ());
246+ AttributeInfo attributeInfo = attributeMap .get (attribute .getName ());
247+ if (attributeInfo == null || attributeInfo .setter == null ) {
248+ return ;
249+ }
250+ attributeInfo .setter .invoke (bean , attribute .getValue ());
239251 } catch (IllegalAccessException | InvocationTargetException e ) {
240252 LOG .severe ("Error during execution: " + e .getMessage ());
241253 }
@@ -257,14 +269,18 @@ public AttributeList getAttributes(String[] attributes) {
257269 }
258270
259271 @ Override
260- public AttributeList setAttributes (AttributeList attributes ) {
272+ public @ Nullable AttributeList setAttributes (AttributeList attributes ) {
261273 return null ;
262274 }
263275
264276 @ Override
265- public Object invoke (String actionName , Object [] params , String [] signature ) {
277+ public @ Nullable Object invoke (String actionName , Object [] params , String [] signature ) {
266278 try {
267- return operationMap .get (actionName ).method .invoke (bean , params );
279+ OperationInfo operationInfo = operationMap .get (actionName );
280+ if (operationInfo == null ) {
281+ return null ;
282+ }
283+ return operationInfo .method .invoke (bean , params );
268284 } catch (IllegalAccessException | InvocationTargetException e ) {
269285 LOG .severe ("Error during execution: " + e .getMessage ());
270286 return null ;
0 commit comments