Skip to content

Commit 1461947

Browse files
author
Araf Karsh Hamid
committed
Added Java 18 Examples
1 parent 8bf6608 commit 1461947

7 files changed

+418
-0
lines changed

JavaExamples.iml

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<component name="NewModuleRootManager" inherit-compiler-output="true">
44
<exclude-output />
55
<content url="file://$MODULE_DIR$">
6+
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
67
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
78
</content>
89
<orderEntry type="inheritedJdk" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
java18.CustomDNSResolverProvider
+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* Copyright (c) 2024 Araf Karsh Hamid
3+
* <p>
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
* <p>
11+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
17+
* THE SOFTWARE.
18+
* <p>
19+
* This program and the accompanying materials are dual-licensed under
20+
* either the terms of the Eclipse Public License v1.0 as published by
21+
* the Eclipse Foundation
22+
* <p>
23+
* or (per the licensee's choosing)
24+
* <p>
25+
* under the terms of the Apache 2 License version 2.0
26+
* as published by the Apache Software Foundation.
27+
*/
28+
package java18;
29+
30+
import java.net.InetAddress;
31+
32+
import static java.lang.System.out;
33+
34+
/**
35+
* JavaExamples / CustomDNSResolverExample
36+
*
37+
* @author: Araf Karsh Hamid
38+
* @version: 0.1
39+
* @date: 2024-09-30T07:54
40+
*/
41+
public class CustomDNSResolverExample {
42+
43+
public static void main(String[] args) {
44+
// Java 18
45+
out.println("JAVA 18 >>>>>--------------------------------------------------------");
46+
out.println("Custom DNS Resolver Example .... (Testing done under Java 23)");
47+
try {
48+
// Test resolving a domain ending in ".fusion"
49+
InetAddress testDomainAddress = InetAddress.getByName("myapp.fusion");
50+
System.out.println("Resolved INTERNAL address for myapp.fusion: " + testDomainAddress);
51+
} catch (Exception e) {
52+
System.out.println("Host Not Found! : "+e.getMessage());
53+
}
54+
try {
55+
// Test resolving a normal domain (e.g., google.com)
56+
InetAddress normalDomainAddress = InetAddress.getByName("google.com");
57+
System.out.println("Resolved EXTERNAL address for google.com: " + normalDomainAddress);
58+
} catch (Exception e) {
59+
System.out.println("Host Not Found! : "+e.getMessage()); }
60+
}
61+
}
+184
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/**
2+
* Copyright (c) 2024 Araf Karsh Hamid
3+
* <p>
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
* <p>
11+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
17+
* THE SOFTWARE.
18+
* <p>
19+
* This program and the accompanying materials are dual-licensed under
20+
* either the terms of the Eclipse Public License v1.0 as published by
21+
* the Eclipse Foundation
22+
* <p>
23+
* or (per the licensee's choosing)
24+
* <p>
25+
* under the terms of the Apache 2 License version 2.0
26+
* as published by the Apache Software Foundation.
27+
*/
28+
package java18;
29+
30+
import javax.naming.NamingException;
31+
import javax.naming.directory.Attribute;
32+
import javax.naming.directory.Attributes;
33+
import javax.naming.directory.DirContext;
34+
import javax.naming.directory.InitialDirContext;
35+
import java.net.InetAddress;
36+
import java.net.UnknownHostException;
37+
import java.net.spi.InetAddressResolver;
38+
import java.net.spi.InetAddressResolverProvider;
39+
import java.util.ArrayList;
40+
import java.util.List;
41+
import java.util.stream.Stream;
42+
43+
/**
44+
* JavaExamples / CustomDNSResolverProvider
45+
*
46+
* Place the file "java.net.spi.InetAddressResolverProvider" in the
47+
* resources/META-INF/services folder.
48+
* Content of the file "java18.CustomDNSResolverProvider"
49+
*
50+
project-root/
51+
├── src/
52+
│ └── main/
53+
│ └── java/
54+
│ └── java18/
55+
│ └── CustomInetAddressResolverProvider.java
56+
├── resources/
57+
└── META-INF/
58+
└── services/
59+
└── java.net.spi.InetAddressResolverProvider
60+
OR
61+
src/
62+
├── main/
63+
│ ├── java/
64+
│ │ └── your/package/name/
65+
│ │ └── CustomInetAddressResolverProvider.java
66+
│ └── resources/
67+
│ └── META-INF/
68+
│ └── services/
69+
│ └── java.net.spi.InetAddressResolverProvider
70+
*
71+
* If the JVM doesn't pick up the file then right-click on the "resources" folder and click the
72+
* option "Mark Director as" Resource Root.
73+
*
74+
* @author: Araf Karsh Hamid
75+
* @version: 0.1
76+
* @date: 2024-09-30T07:54
77+
*/
78+
public class CustomDNSResolverProvider extends InetAddressResolverProvider {
79+
@Override
80+
public InetAddressResolver get(Configuration configuration) {
81+
return new CustomInetAddressResolver();
82+
}
83+
84+
/**
85+
* {@return the name of this provider, or {@code null} if unnamed}
86+
*/
87+
@Override
88+
public String name() {
89+
return "";
90+
}
91+
92+
static class CustomInetAddressResolver implements InetAddressResolver {
93+
94+
@Override
95+
public Stream<InetAddress> lookupByName(String host, LookupPolicy lookupPolicy) throws UnknownHostException {
96+
try {
97+
// System.out.println("Inside CustomDNSResolverProvider..... ");
98+
// Custom rule: return a fixed IP address for any domain ending in ".fusion"
99+
if (host.endsWith(".fusion")) {
100+
return Stream.of(InetAddress.getByName("10.18.36.54"));
101+
} else {
102+
// Fallback to the default resolution mechanism
103+
// Bypass recursion for default resolution mechanism
104+
return lookupUsingJNDI(host);
105+
}
106+
} catch (Exception e) {
107+
System.out.println("Host Not Found "+host+" ERROR: "+e.getMessage());
108+
// e.printStackTrace();
109+
return Stream.empty();
110+
}
111+
}
112+
113+
/**
114+
* 1. Proper Attribute Handling:
115+
* The Attributes object from the JNDI context is properly parsed.
116+
* The “A” record is for IPv4 addresses.
117+
* The “AAAA” record is for IPv6 addresses.
118+
* The code checks if these attributes exist and iterates over their values.
119+
* 2. Trim Strings:
120+
* The IP address strings retrieved are trimmed using .trim() before passing them to
121+
* InetAddress.getByName() to ensure there are no extra spaces that can cause parsing
122+
* issues.
123+
* 3. Improved Error Handling:
124+
* Each potential DNS record (IPv4 or IPv6) is individually checked and converted to
125+
* an InetAddress. Any parsing issues will be caught, but won’t stop the entire lookup
126+
* process.
127+
*
128+
* @param host
129+
* @return
130+
*/
131+
private Stream<InetAddress> lookupUsingJNDI(String host) {
132+
List<InetAddress> addressList = new ArrayList<>();
133+
try {
134+
DirContext ictx = new InitialDirContext();
135+
Attributes attrs = ictx.getAttributes("dns:/" + host);
136+
137+
// Attempt to retrieve both IPv4 ("A") and IPv6 ("AAAA") records
138+
Attribute aRecord = attrs.get("A");
139+
Attribute aaaaRecord = attrs.get("AAAA");
140+
141+
// Process A records (IPv4)
142+
if (aRecord != null) {
143+
for (int i = 0; i < aRecord.size(); i++) {
144+
String ip = (String) aRecord.get(i);
145+
try {
146+
InetAddress address = InetAddress.getByName(ip.trim());
147+
addressList.add(address);
148+
} catch (UnknownHostException e) {
149+
e.printStackTrace();
150+
}
151+
}
152+
}
153+
// Process AAAA records (IPv6)
154+
if (aaaaRecord != null) {
155+
for (int i = 0; i < aaaaRecord.size(); i++) {
156+
String ip = (String) aaaaRecord.get(i);
157+
try {
158+
InetAddress address = InetAddress.getByName(ip.trim());
159+
addressList.add(address);
160+
} catch (UnknownHostException e) {
161+
e.printStackTrace();
162+
}
163+
}
164+
}
165+
166+
} catch (NamingException e) {
167+
e.printStackTrace();
168+
}
169+
return addressList.stream();
170+
}
171+
172+
@Override
173+
public String lookupByAddress(byte[] addr) throws UnknownHostException {
174+
try {
175+
// Fallback to default reverse lookup mechanism
176+
InetAddress address = InetAddress.getByAddress(addr);
177+
return address.getHostName();
178+
} catch (Exception e) {
179+
e.printStackTrace();
180+
return null;
181+
}
182+
}
183+
}
184+
}

src/java18/FinalizerExample.java

+29
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@
3939
* Java 18 deprecates the finalization mechanism for removal, which encourages developers to use
4040
* alternative methods like AutoCloseable.
4141
*
42+
* Old Way: Using finalize()
43+
*
44+
* In the older Java versions, developers often used the finalize() method to release resources,
45+
* such as closing a file or releasing memory. However, this approach has significant downsides,
46+
* such as unpredictable timing of finalization and high overhead for garbage collection.
47+
*
48+
* New Way: Using AutoCloseable and try-with-resources
49+
*
50+
* Java 18 encourages developers to use AutoCloseable with try-with-resources to release
51+
* resources deterministically and effectively, addressing the issues found with finalize().
52+
*
4253
* @author: Araf Karsh Hamid
4354
* @version: 0.1
4455
* @date: 2024-09-29T21:52
@@ -77,6 +88,15 @@ public void printResource() {
7788
out.println(new Date()+" | Resource = "+resource);
7889
}
7990

91+
/**
92+
* finalize()
93+
* • finalize() is invoked by the garbage collector just before an object is destroyed.
94+
* • This method can be used to release resources, but it has major drawbacks:
95+
* • Unpredictable timing: There’s no guarantee on when finalize() will be called.
96+
* • Performance: The use of finalizers adds an overhead to garbage collection and can cause delays.
97+
* • Memory Leaks: Objects with a finalize() method often take longer to be collected.
98+
* @throws Throwable
99+
*/
80100
@Override
81101
protected void finalize() throws Throwable {
82102
try {
@@ -103,6 +123,15 @@ public void printResource() {
103123
out.println(new Date()+" | Resource = "+resource);
104124
}
105125

126+
/**
127+
* - AutoCloseable Interface: Implementing AutoCloseable allows the object to be used in
128+
* a try-with-resources block, where close() is called automatically at the end of the block.
129+
* - try-with-resources: This construct ensures that the resource is closed automatically,
130+
* which is deterministic and occurs immediately after the block is exited.
131+
* - Clearer Lifecycle Management: Resources are properly closed as soon as they’re no
132+
* longer needed, without relying on the unpredictable garbage collector behavior.
133+
* @throws Exception
134+
*/
106135
@Override
107136
public void close() throws Exception {
108137
out.println(new Date()+" | Releasing resource in finalize: " + resource);
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/**
2+
* Copyright (c) 2024 Araf Karsh Hamid
3+
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
11+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
17+
* THE SOFTWARE.
18+
19+
* This program and the accompanying materials are dual-licensed under
20+
* either the terms of the Eclipse Public License v1.0 as published by
21+
* the Eclipse Foundation
22+
23+
* or (per the licensee's choosing)
24+
25+
* under the terms of the Apache 2 License version 2.0
26+
* as published by the Apache Software Foundation.
27+
*/
28+
package java18;
29+
30+
import static java.lang.System.out;
31+
32+
/**
33+
* JEP 420: Pattern Matching for switch (Second Preview)
34+
*
35+
* Pattern matching for switch has been improved in Java 18 to allow more flexible and readable
36+
* code.
37+
*
38+
* @author: Araf Karsh Hamid
39+
* @version:
40+
* @date:
41+
*/
42+
public class SwitchExpressionExample {
43+
44+
public static void main (String[] args) {
45+
// Java 17
46+
out.println("JAVA 17 >>>>>--------------------------------------------------------");
47+
out.println("Pattern Matching in Java 17");
48+
Object o = 127;
49+
switch (o) {
50+
case String s -> out.println("String: " + s);
51+
case Integer i -> out.println("Integer: "+ i);
52+
case Long l -> out.println("Long: "+ l);
53+
default -> out.println("Other: "+ o);
54+
}
55+
// Java 18
56+
out.println("JAVA 18 >>>>>--------------------------------------------------------");
57+
out.println("Pattern Matching in Java 18");
58+
out.println(typeFinder("Hello"));
59+
out.println(typeFinder(127));
60+
out.println(typeFinder(null));
61+
out.println(typeFinder(3.14f));
62+
63+
}
64+
65+
public static String typeFinder(Object obj) {
66+
return switch (obj) {
67+
case String s -> "String: " + s;
68+
case Integer i -> "Integer: " + i;
69+
case null -> "Null value";
70+
default -> "Unknown type";
71+
};
72+
}
73+
}

0 commit comments

Comments
 (0)