@@ -192,11 +192,21 @@ void shouldRejectUnsafeBaseUrlAtHermesChatClientAndSseClient() {
192192 // HermesChatClient 单参构造器存在;HermesSseClient 三参,反射构造让守卫
193193 // 在 super(...) 里先抛 IAE(如不安全),反之抛 IllegalArgumentException 不安全。
194194 assertThrows (IllegalArgumentException .class , () -> new HermesChatClient (config ));
195+ // 按形参类型匹配三参构造器(三参:config, objectMapper, httpClient)——
196+ // 避免依赖 Jackson 2/3 的具体 ObjectMapper 类名(两分支传递依赖不同)。
197+ java .lang .reflect .Constructor <?> sseCtor = null ;
198+ for (java .lang .reflect .Constructor <?> c : HermesSseClient .class .getConstructors ()) {
199+ Class <?>[] params = c .getParameterTypes ();
200+ if (params .length == 3
201+ && params [0 ] == HermesHttpClientConfig .class
202+ && params [2 ] == okhttp3 .OkHttpClient .class ) {
203+ sseCtor = c ;
204+ break ;
205+ }
206+ }
207+ assertNotNull (sseCtor , "HermesSseClient (config, objectMapper, httpClient) constructor must exist" );
195208 try {
196- Class <?> objectMapperCls = Class .forName ("tools.jackson.databind.ObjectMapper" );
197- HermesSseClient .class .getConstructor (HermesHttpClientConfig .class ,
198- objectMapperCls , okhttp3 .OkHttpClient .class )
199- .newInstance (config , null , null );
209+ sseCtor .newInstance (config , null , null );
200210 throw new AssertionError ("HermesSseClient construction should have rejected the unsafe baseUrl" );
201211 } catch (java .lang .reflect .InvocationTargetException ite ) {
202212 Throwable cause = ite .getCause ();
@@ -205,20 +215,11 @@ void shouldRejectUnsafeBaseUrlAtHermesChatClientAndSseClient() {
205215 throw new AssertionError (
206216 "Expected EndpointGuard IllegalArgumentException, got " + cause );
207217 }
208- } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | ClassNotFoundException e ) {
218+ } catch (InstantiationException | IllegalAccessException e ) {
209219 throw new IllegalStateException ("Reflective HermesSseClient construction failed" , e );
210220 }
211221 }
212222
213- @ Test
214- void shouldAcceptDefaultLoopbackWhenSetViaGuardedSetter () {
215- // 默认 baseUrl 是 http://localhost:8642——setter 会立刻拒绝;
216- // 这是默认值的预期失败路径,证明防御点在构造期就生效。
217- HermesHttpClientConfig config = new HermesHttpClientConfig ();
218- assertThrows (IllegalArgumentException .class ,
219- () -> config .setBaseUrl (HermesApiConstants .DEFAULT_SERVER_URL ));
220- }
221-
222223 @ Test
223224 void shouldCoverBranchAndPortVariants () {
224225 // 端口不应影响校验结论
0 commit comments