1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.net;
18
19 import java.lang.reflect.Constructor;
20 import java.lang.reflect.InvocationTargetException;
21 import java.lang.reflect.Method;
22 import java.util.Hashtable;
23 import java.util.Map;
24 import org.apache.logging.log4j.Logger;
25 import org.apache.logging.log4j.core.config.plugins.Plugin;
26 import org.apache.logging.log4j.status.StatusLogger;
27
28
29
30
31
32 @Plugin(name = "multicastdns", category = "Core", elementType = "advertiser", printObject = false)
33 public class MulticastDNSAdvertiser implements Advertiser {
34 protected static final Logger LOGGER = StatusLogger.getLogger();
35 private static Object jmDNS = initializeJMDNS();
36
37 private static Class<?> jmDNSClass;
38 private static Class<?> serviceInfoClass;
39
40 public MulticastDNSAdvertiser()
41 {
42
43 }
44
45
46
47
48
49
50
51
52
53
54 public Object advertise(Map<String, String> properties) {
55
56 String protocol = properties.get("protocol");
57 String zone = "._log4j._"+(protocol != null ? protocol : "tcp") + ".local.";
58
59 String portString = properties.get("port");
60 int port = (portString != null ? Integer.parseInt(portString) : 4555);
61
62 String name = properties.get("name");
63
64
65 if (jmDNS != null)
66 {
67 boolean isVersion3 = false;
68 try {
69
70 jmDNSClass.getMethod("create", (Class[])null);
71 isVersion3 = true;
72 } catch (NoSuchMethodException e) {
73
74 }
75 System.out.println("building: " + zone);
76 Object serviceInfo;
77 if (isVersion3) {
78 serviceInfo = buildServiceInfoVersion3(zone, port, name, properties);
79 } else {
80 serviceInfo = buildServiceInfoVersion1(zone, port, name, properties);
81 }
82
83 try {
84 Method method = jmDNSClass.getMethod("registerService", new Class[]{serviceInfoClass});
85 method.invoke(jmDNS, serviceInfo);
86 } catch(IllegalAccessException e) {
87 LOGGER.warn("Unable to invoke registerService method", e);
88 } catch(NoSuchMethodException e) {
89 LOGGER.warn("No registerService method", e);
90 } catch(InvocationTargetException e) {
91 LOGGER.warn("Unable to invoke registerService method", e);
92 }
93 return serviceInfo;
94 }
95 else
96 {
97 LOGGER.warn("JMDNS not available - will not advertise ZeroConf support");
98 return null;
99 }
100 }
101
102
103
104
105
106 public void unadvertise(Object serviceInfo) {
107 if (jmDNS != null) {
108 try {
109 Method method = jmDNSClass.getMethod("unregisterService", new Class[]{serviceInfoClass});
110 method.invoke(jmDNS, serviceInfo);
111 } catch(IllegalAccessException e) {
112 LOGGER.warn("Unable to invoke unregisterService method", e);
113 } catch(NoSuchMethodException e) {
114 LOGGER.warn("No unregisterService method", e);
115 } catch(InvocationTargetException e) {
116 LOGGER.warn("Unable to invoke unregisterService method", e);
117 }
118 }
119 }
120
121 private static Object createJmDNSVersion1()
122 {
123 try {
124 return jmDNSClass.newInstance();
125 } catch (InstantiationException e) {
126 LOGGER.warn("Unable to instantiate JMDNS", e);
127 } catch (IllegalAccessException e) {
128 LOGGER.warn("Unable to instantiate JMDNS", e);
129 }
130 return null;
131 }
132
133 private static Object createJmDNSVersion3()
134 {
135 try {
136 Method jmDNSCreateMethod = jmDNSClass.getMethod("create", (Class[])null);
137 return jmDNSCreateMethod.invoke(null, (Object[])null);
138 } catch (IllegalAccessException e) {
139 LOGGER.warn("Unable to instantiate jmdns class", e);
140 } catch (NoSuchMethodException e) {
141 LOGGER.warn("Unable to access constructor", e);
142 } catch (InvocationTargetException e) {
143 LOGGER.warn("Unable to call constructor", e);
144 }
145 return null;
146 }
147
148 private Object buildServiceInfoVersion1(String zone, int port, String name, Map<String, String> properties) {
149
150 Hashtable<String, String> hashtableProperties = new Hashtable<String, String>(properties);
151 try {
152 Class[] args = new Class[6];
153 args[0] = String.class;
154 args[1] = String.class;
155 args[2] = int.class;
156 args[3] = int.class;
157 args[4] = int.class;
158 args[5] = Hashtable.class;
159 Constructor<?> constructor = serviceInfoClass.getConstructor(args);
160 Object[] values = new Object[6];
161 values[0] = zone;
162 values[1] = name;
163 values[2] = port;
164 values[3] = 0;
165 values[4] = 0;
166 values[5] = hashtableProperties;
167 return constructor.newInstance(values);
168 } catch (IllegalAccessException e) {
169 LOGGER.warn("Unable to construct ServiceInfo instance", e);
170 } catch (NoSuchMethodException e) {
171 LOGGER.warn("Unable to get ServiceInfo constructor", e);
172 } catch (InstantiationException e) {
173 LOGGER.warn("Unable to construct ServiceInfo instance", e);
174 } catch (InvocationTargetException e) {
175 LOGGER.warn("Unable to construct ServiceInfo instance", e);
176 }
177 return null;
178 }
179
180 private Object buildServiceInfoVersion3(String zone, int port, String name, Map<String, String> properties) {
181 try {
182 Class[] args = new Class[6];
183 args[0] = String.class;
184 args[1] = String.class;
185 args[2] = int.class;
186 args[3] = int.class;
187 args[4] = int.class;
188 args[5] = Map.class;
189 Method serviceInfoCreateMethod = serviceInfoClass.getMethod("create", args);
190 Object[] values = new Object[6];
191 values[0] = zone;
192 values[1] = name;
193 values[2] = port;
194 values[3] = 0;
195 values[4] = 0;
196 values[5] = properties;
197 return serviceInfoCreateMethod.invoke(null, values);
198 } catch (IllegalAccessException e) {
199 LOGGER.warn("Unable to invoke create method", e);
200 } catch (NoSuchMethodException e) {
201 LOGGER.warn("Unable to find create method", e);
202 } catch (InvocationTargetException e) {
203 LOGGER.warn("Unable to invoke create method", e);
204 }
205 return null;
206 }
207
208 private static Object initializeJMDNS() {
209 try {
210 jmDNSClass = Class.forName("javax.jmdns.JmDNS");
211 serviceInfoClass = Class.forName("javax.jmdns.ServiceInfo");
212
213 boolean isVersion3 = false;
214 try {
215
216 jmDNSClass.getMethod("create", (Class[])null);
217 isVersion3 = true;
218 } catch (NoSuchMethodException e) {
219
220 }
221
222 if (isVersion3) {
223 return createJmDNSVersion3();
224 } else {
225 return createJmDNSVersion1();
226 }
227 } catch (ClassNotFoundException e) {
228 LOGGER.warn("JmDNS or serviceInfo class not found", e);
229 } catch (ExceptionInInitializerError e2) {
230 LOGGER.warn("JmDNS or serviceInfo class not found", e2);
231 }
232 return null;
233 }
234 }