From dce4e681500c85efdf9b9f680da8e31c19bf2d08 Mon Sep 17 00:00:00 2001 From: ericek111 Date: Thu, 13 Aug 2026 23:46:56 +0000 Subject: [PATCH] Drop the commons-lang and dnsjava dependencies Both were pulled in for a single call each: commons-lang for ConstructorUtils.invokeConstructor when building a packet handler, and dnsjava for the _ts3._udp SRV lookup. Together they added over a megabyte to a shaded jar (and dnsjava drops jnamed/update classes into the jar root). Plain reflection and JNDI's dns: provider cover both. Also drop the BouncyCastleProvider registration: every digest here is requested by a name the SUN provider already answers, so the only thing it accomplished was keeping the whole JCE provider, the post-quantum suite and the X.509 stack reachable for a shaded-jar tree-shaker. Co-Authored-By: Claude Opus 5 --- pom.xml | 12 ---- .../manevolent/ts3j/protocol/TS3DNS.java | 69 ++++++++++++++----- .../client/AbstractTeamspeakClientSocket.java | 9 ++- .../github/manevolent/ts3j/util/Ts3Crypt.java | 4 -- 4 files changed, 58 insertions(+), 36 deletions(-) diff --git a/pom.xml b/pom.xml index 9f5c3a6..a6d53c3 100644 --- a/pom.xml +++ b/pom.xml @@ -40,18 +40,6 @@ 1.67 - - commons-lang - commons-lang - 2.6 - - - - dnsjava - dnsjava - 2.1.8 - - org.ini4j ini4j diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/TS3DNS.java b/src/main/java/com/github/manevolent/ts3j/protocol/TS3DNS.java index 8b6fab9..1356391 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/TS3DNS.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/TS3DNS.java @@ -1,13 +1,13 @@ package com.github.manevolent.ts3j.protocol; -import org.xbill.DNS.*; - +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.InitialDirContext; import java.io.IOException; import java.net.InetSocketAddress; -import java.net.SocketAddress; import java.net.UnknownHostException; import java.util.*; -import java.util.stream.Collectors; public class TS3DNS { private static final int TS3_VOICE_DEFAULT_PORT = 9987; @@ -18,23 +18,56 @@ public class TS3DNS { private static final String DNS_PREFIX_TCP = "_tsdns._tcp."; private static final String DNS_PREFIX_UDP = "_ts3._udp."; + /** + * SRV record, as returned by JNDI: "priority weight port target." + */ + private static final class SrvRecord { + private final int priority, weight, port; + private final String target; + + private SrvRecord(String record) { + String[] parts = record.trim().split("\\s+"); + if (parts.length < 4) throw new IllegalArgumentException("malformed SRV record: " + record); + + this.priority = Integer.parseInt(parts[0]); + this.weight = Integer.parseInt(parts[1]); + this.port = Integer.parseInt(parts[2]); + + // Trim the trailing dot of the fully-qualified target name. + String target = parts[3]; + this.target = target.endsWith(".") ? target.substring(0, target.length() - 1) : target; + } + } + private static List lookupSRV(String domain) throws IOException { - org.xbill.DNS.Record[] records = new Lookup(domain, Type.SRV).run(); + Attribute attribute; - if (records == null || records.length <= 0) throw new UnknownHostException("Host not found"); + try { + Attributes attributes = new InitialDirContext().getAttributes("dns:/" + domain, new String[] { "SRV" }); + attribute = attributes.get("SRV"); + } catch (NamingException e) { + throw new UnknownHostException("Host not found: " + domain); + } - return Arrays.stream(records) - .filter(Objects::nonNull) - .map(x -> (SRVRecord) x) - .filter(x -> x.getTarget() != null) - .sorted((a, b) -> { - // Loose sorting - int prioComp = Integer.compare(a.getPriority(), b.getPriority()); - if (prioComp != 0) return prioComp; - else return Integer.compare(a.getWeight(), b.getWeight()); - }) - .map(x -> new InetSocketAddress(x.getTarget().toString(), x.getPort())) - .collect(Collectors.toList()); + if (attribute == null || attribute.size() <= 0) throw new UnknownHostException("Host not found"); + + List records = new ArrayList<>(attribute.size()); + + try { + for (int i = 0; i < attribute.size(); i++) + records.add(new SrvRecord((String) attribute.get(i))); + } catch (NamingException e) { + throw new IOException(e); + } + + // Loose sorting + records.sort(Comparator.comparingInt((SrvRecord x) -> x.priority).thenComparingInt(x -> x.weight)); + + List addresses = new ArrayList<>(records.size()); + for (SrvRecord record : records) + addresses.add(new InetSocketAddress(record.target, record.port)); + + return addresses; } public static List lookup(String domain) throws IOException { diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/AbstractTeamspeakClientSocket.java b/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/AbstractTeamspeakClientSocket.java index b9353da..ebabafc 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/AbstractTeamspeakClientSocket.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/AbstractTeamspeakClientSocket.java @@ -24,7 +24,6 @@ import com.github.manevolent.ts3j.util.QuickLZ; import com.github.manevolent.ts3j.util.Ts3Crypt; import com.github.manevolent.ts3j.util.Ts3Debugging; import com.github.manevolent.ts3j.util.Pair; -import org.apache.commons.lang.reflect.ConstructorUtils; import org.bouncycastle.crypto.InvalidCipherTextException; import java.io.EOFException; @@ -1466,6 +1465,12 @@ public abstract class AbstractTeamspeakClientSocket } private PacketHandler createHandler(Class clazz) throws ReflectiveOperationException { - return (PacketHandler) ConstructorUtils.invokeConstructor(clazz, this); + for (java.lang.reflect.Constructor constructor : clazz.getConstructors()) { + Class[] parameters = constructor.getParameterTypes(); + if (parameters.length == 1 && parameters[0].isInstance(this)) + return (PacketHandler) constructor.newInstance(this); + } + + throw new NoSuchMethodException(clazz.getName() + " has no constructor accepting " + getClass().getName()); } } diff --git a/src/main/java/com/github/manevolent/ts3j/util/Ts3Crypt.java b/src/main/java/com/github/manevolent/ts3j/util/Ts3Crypt.java index bddd882..caf2976 100644 --- a/src/main/java/com/github/manevolent/ts3j/util/Ts3Crypt.java +++ b/src/main/java/com/github/manevolent/ts3j/util/Ts3Crypt.java @@ -28,10 +28,6 @@ import java.security.*; import java.util.*; public final class Ts3Crypt { - static { - Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); - } - public static byte[] hash128(byte[] data, int offs, int len) { try { MessageDigest digest = MessageDigest.getInstance("SHA1");