<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Clojure Q&amp;A - Recent questions tagged reflection</title>
<link>https://ask.clojure.org/index.php/tag/reflection</link>
<description></description>
<item>
<title>Refection warning even with type hinting</title>
<link>https://ask.clojure.org/index.php/14622/refection-warning-even-with-type-hinting</link>
<description>&lt;p&gt;I have the function&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn println-err [^String s]
  (.println *err* s))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When I set &lt;code&gt;*warn-on-reflections*&lt;/code&gt;, I get&lt;br&gt;
&amp;gt; call to method println can't be resolved (target class is unknown).&lt;/p&gt;
&lt;p&gt;I can work around this with &lt;code&gt;(binding [*out* *err*] (println s)))&lt;/code&gt;, but I'd like to know why I'm getting this reflection warning even though I'm telling the compiler the type.&lt;/p&gt;
&lt;p&gt;Note: I have zero Java experience.&lt;/p&gt;
</description>
<category>Java Interop</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14622/refection-warning-even-with-type-hinting</guid>
<pubDate>Fri, 11 Jul 2025 14:48:42 +0000</pubDate>
</item>
<item>
<title>Method with int parameter is called, although the provided parameter is long</title>
<link>https://ask.clojure.org/index.php/14612/method-with-parameter-called-although-provided-parameter</link>
<description>&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/LWJGL/lwjgl3/blob/3.3.6/modules/lwjgl/assimp/src/generated/java/org/lwjgl/assimp/AIMesh.java&quot;&gt;AIMesh&lt;/a&gt; provides several overloaded &lt;code&gt;create&lt;/code&gt; methods. There is one with an &lt;code&gt;int&lt;/code&gt; parameter and another one with a &lt;code&gt;long&lt;/code&gt; parameter. They have very different semantics.&lt;/p&gt;
&lt;p&gt;This code snippet intends to call the one with the &lt;code&gt;long&lt;/code&gt; parameter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn read-model
  &quot;read a 3D model from a file&quot;
  [path]
  (let [scene (Assimp/aiImportFile path (bit-or Assimp/aiProcess_Triangulate
                                                Assimp/aiProcess_FlipUVs))]
    (if (= scene nil)
      (println (Assimp/aiGetErrorString))
      (for [index (range (.mNumMeshes scene))]
        (let [pointer (.get (.mMeshes scene) index)]
          (assert (= (type pointer) java.lang.Long))
          (AIMesh/create pointer))))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The assertion right before the problematic call makes sure that &lt;code&gt;pointer&lt;/code&gt; is indeed a &lt;code&gt;long&lt;/code&gt;; but nevertheless the &lt;code&gt;int&lt;/code&gt; overload of &lt;code&gt;create&lt;/code&gt; is called, as can be verified in the stack trace:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{:clojure.main/message
 &quot;Execution error (IllegalArgumentException) at java.nio.Buffer/createCapacityException (Buffer.java:290).\ncapacity &amp;lt; 0: (-689151616 &amp;lt; 0)\n&quot;,
 :clojure.main/triage
 {:clojure.error/class java.lang.IllegalArgumentException,
  :clojure.error/line 290,
  :clojure.error/cause &quot;capacity &amp;lt; 0: (-689151616 &amp;lt; 0)&quot;,
  :clojure.error/symbol java.nio.Buffer/createCapacityException,
  :clojure.error/source &quot;Buffer.java&quot;,
  :clojure.error/phase :execution},
 :clojure.main/trace
 {:via
  [{:type clojure.lang.Compiler$CompilerException,
    :message
    &quot;Syntax error macroexpanding at (learnopengl/core.clj:12:1).&quot;,
    :data
    {:clojure.error/phase :execution,
     :clojure.error/line 12,
     :clojure.error/column 1,
     :clojure.error/source &quot;learnopengl/core.clj&quot;},
    :at [clojure.lang.Compiler load &quot;Compiler.java&quot; 7665]}
   {:type java.lang.IllegalArgumentException,
    :message &quot;capacity &amp;lt; 0: (-689151616 &amp;lt; 0)&quot;,
    :at [java.nio.Buffer createCapacityException &quot;Buffer.java&quot; 290]}],
  :trace
  [[java.nio.Buffer createCapacityException &quot;Buffer.java&quot; 290]
   [java.nio.Buffer &amp;lt;init&amp;gt; &quot;Buffer.java&quot; 253]
   [java.nio.ByteBuffer &amp;lt;init&amp;gt; &quot;ByteBuffer.java&quot; 316]
   [java.nio.ByteBuffer &amp;lt;init&amp;gt; &quot;ByteBuffer.java&quot; 324]
   [java.nio.MappedByteBuffer &amp;lt;init&amp;gt; &quot;MappedByteBuffer.java&quot; 113]
   [java.nio.DirectByteBuffer &amp;lt;init&amp;gt; &quot;DirectByteBuffer.java&quot; 107]
   [java.nio.ByteBuffer allocateDirect &quot;ByteBuffer.java&quot; 360]
   [org.lwjgl.system.Struct __create &quot;Struct.java&quot; 118]
   [org.lwjgl.assimp.AIMesh create &quot;AIMesh.java&quot; 487]
   [jdk.internal.reflect.DirectMethodHandleAccessor
    invoke
    &quot;DirectMethodHandleAccessor.java&quot;
    103]
   [java.lang.reflect.Method invoke &quot;Method.java&quot; 580]
   [clojure.lang.Reflector invokeMatchingMethod &quot;Reflector.java&quot; 167]
   [clojure.lang.Reflector invokeStaticMethod &quot;Reflector.java&quot; 332]
   [learnopengl.mesh_model$read_model$iter__332__336$fn__337$fn__338
    invoke
    &quot;mesh_model.clj&quot;
    66]
   [learnopengl.mesh_model$read_model$iter__332__336$fn__337
    invoke
    &quot;mesh_model.clj&quot;
    63]
   [clojure.lang.LazySeq sval &quot;LazySeq.java&quot; 42]
   [clojure.lang.LazySeq seq &quot;LazySeq.java&quot; 51]
   [clojure.lang.RT seq &quot;RT.java&quot; 535]
   [clojure.lang.RT countFrom &quot;RT.java&quot; 650]
   [clojure.lang.RT count &quot;RT.java&quot; 643]
   [learnopengl.core$eval351 invokeStatic &quot;core.clj&quot; 12]
   [learnopengl.core$eval351 invoke &quot;core.clj&quot; 12]
   [clojure.lang.Compiler eval &quot;Compiler.java&quot; 7194]
   [clojure.lang.Compiler load &quot;Compiler.java&quot; 7653]
   [clojure.lang.RT loadResourceScript &quot;RT.java&quot; 381]
   [clojure.lang.RT loadResourceScript &quot;RT.java&quot; 372]
   [clojure.lang.RT load &quot;RT.java&quot; 459]
   [clojure.lang.RT load &quot;RT.java&quot; 424]
   [clojure.core$load$fn__6908 invoke &quot;core.clj&quot; 6161]
   [clojure.core$load invokeStatic &quot;core.clj&quot; 6160]
   [clojure.core$load doInvoke &quot;core.clj&quot; 6144]
   [clojure.lang.RestFn invoke &quot;RestFn.java&quot; 408]
   [clojure.core$load_one invokeStatic &quot;core.clj&quot; 5933]
   [clojure.core$load_one invoke &quot;core.clj&quot; 5928]
   [clojure.core$load_lib$fn__6850 invoke &quot;core.clj&quot; 5975]
   [clojure.core$load_lib invokeStatic &quot;core.clj&quot; 5974]
   [clojure.core$load_lib doInvoke &quot;core.clj&quot; 5953]
   [clojure.lang.RestFn applyTo &quot;RestFn.java&quot; 142]
   [clojure.core$apply invokeStatic &quot;core.clj&quot; 669]
   [clojure.core$load_libs invokeStatic &quot;core.clj&quot; 6016]
   [clojure.core$load_libs doInvoke &quot;core.clj&quot; 6000]
   [clojure.lang.RestFn applyTo &quot;RestFn.java&quot; 137]
   [clojure.core$apply invokeStatic &quot;core.clj&quot; 669]
   [clojure.core$require invokeStatic &quot;core.clj&quot; 6038]
   [clojure.core$require doInvoke &quot;core.clj&quot; 6038]
   [clojure.lang.RestFn invoke &quot;RestFn.java&quot; 408]
   [user$eval140$fn__144 invoke &quot;form-init15974239925031016013.clj&quot; 1]
   [user$eval140 invokeStatic &quot;form-init15974239925031016013.clj&quot; 1]
   [user$eval140 invoke &quot;form-init15974239925031016013.clj&quot; 1]
   [clojure.lang.Compiler eval &quot;Compiler.java&quot; 7194]
   [clojure.lang.Compiler eval &quot;Compiler.java&quot; 7184]
   [clojure.lang.Compiler load &quot;Compiler.java&quot; 7653]
   [clojure.lang.Compiler loadFile &quot;Compiler.java&quot; 7591]
   [clojure.main$load_script invokeStatic &quot;main.clj&quot; 475]
   [clojure.main$init_opt invokeStatic &quot;main.clj&quot; 477]
   [clojure.main$init_opt invoke &quot;main.clj&quot; 477]
   [clojure.main$initialize invokeStatic &quot;main.clj&quot; 508]
   [clojure.main$null_opt invokeStatic &quot;main.clj&quot; 542]
   [clojure.main$null_opt invoke &quot;main.clj&quot; 539]
   [clojure.main$main invokeStatic &quot;main.clj&quot; 664]
   [clojure.main$main doInvoke &quot;main.clj&quot; 616]
   [clojure.lang.RestFn applyTo &quot;RestFn.java&quot; 137]
   [clojure.lang.Var applyTo &quot;Var.java&quot; 705]
   [clojure.main main &quot;main.java&quot; 40]],
  :cause &quot;capacity &amp;lt; 0: (-689151616 &amp;lt; 0)&quot;,
  :phase :execution}}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/cyberdynesoftware/learnopengl/commit/6e0943c11d51a46591dbdd716f4216247aef9ba3&quot;&gt;repository&lt;/a&gt; contains the full code to reproduce the error. &lt;code&gt;read-model&lt;/code&gt; is defined in mesh-model.clj.&lt;/p&gt;
&lt;p&gt;I ran this with Clojure version 1.11.1 and Java version:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;openjdk 21.0.7 2025-04-15
OpenJDK Runtime Environment (Red_Hat-21.0.7.0.6-2) (build 21.0.7+6)
OpenJDK 64-Bit Server VM (Red_Hat-21.0.7.0.6-2) (build 21.0.7+6, mixed mode, sharing)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There was a previous question on &lt;a rel=&quot;nofollow&quot; href=&quot;https://stackoverflow.com/questions/79689152/reading-a-3d-model-with-lwjgl-assimp-failes-in-clojure&quot;&gt;stackoverflow&lt;/a&gt; leading to this question.&lt;/p&gt;
</description>
<category>Java Interop</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14612/method-with-parameter-called-although-provided-parameter</guid>
<pubDate>Sat, 05 Jul 2025 21:13:00 +0000</pubDate>
</item>
<item>
<title>No path in loop recur arg warning</title>
<link>https://ask.clojure.org/index.php/14126/no-path-in-loop-recur-arg-warning</link>
<description>&lt;p&gt;Reflection warnings, such as for reflective method calls, are printed with the full source path (&lt;code&gt;Compiler/SOURCE_PATH&lt;/code&gt;). This is different in case of the warning about &lt;code&gt;loop&lt;/code&gt; recur args,  printed with the source filename only (&lt;code&gt;Compiler/SOURCE&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(set! *warn-on-reflection* true)

(defn reflective-method-call [] (.substring (try &quot;&quot;) 0))

(defn boxed-recur-arg [] (loop [i 0] (recur (try i))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;...which prints:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Reflection warning, /home/pawel/dev/project/src/core.clj:22:33 - call to method substring can't be resolved (target class is unknown).
core.clj:24 recur arg for primitive local: i is not matching primitive, had: Object, needed: long
Auto-boxing loop arg: i
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IMHO, the path is useful, especially if the filename is generic and inside a dependency.&lt;/p&gt;
</description>
<category>Clojure</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14126/no-path-in-loop-recur-arg-warning</guid>
<pubDate>Sat, 21 Sep 2024 13:12:31 +0000</pubDate>
</item>
<item>
<title>Why isn't there type inference for self-evident cases?</title>
<link>https://ask.clojure.org/index.php/11860/why-isnt-there-type-inference-for-self-evident-cases</link>
<description>&lt;p&gt;I often find myself addressing reflection warnings by placing annotations which type is completely obvious:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(def ^String foo &quot;bar&quot;) ;; adding ^String fixes reflection warnings elsewhere
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;&quot;bar&quot;&lt;/code&gt; is a String, that is unmistakably known at compile-time, so it seems to me that I'm doing grunt work, and also creating something that might become outdated later.&lt;/p&gt;
&lt;p&gt;Has it been considered to add &quot;type inference&quot; for such straightforward cases?&lt;/p&gt;
&lt;p&gt;(&quot;type inference&quot; is probably an exaggerated term for this use case)&lt;/p&gt;
&lt;p&gt;...I can imagine at least one objection: &lt;code&gt;(def ^CharSequence foo &quot;bar&quot;)&lt;/code&gt; can also be accurate and useful. But a good default would be to infer the type of &lt;em&gt;x&lt;/em&gt; to be the &lt;em&gt;x&lt;/em&gt;'s class - if a user wanted to annotate &lt;em&gt;x&lt;/em&gt; as one of its ancestors (here: CharSequence, Object), he could override the inferred default by hand.&lt;/p&gt;
</description>
<category>Java Interop</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11860/why-isnt-there-type-inference-for-self-evident-cases</guid>
<pubDate>Thu, 05 May 2022 08:49:55 +0000</pubDate>
</item>
<item>
<title>Reflection warnings in clojure.data.xml (URLEncoder, URLDecoder)?</title>
<link>https://ask.clojure.org/index.php/11013/reflection-warnings-clojure-data-xml-urlencoder-urldecoder</link>
<description>&lt;p&gt;Is reflection necessary to encode or decode XML namespace names?  This reflection is in a &quot;definline&quot;, so it might be sailing into undesired headwinds.&lt;/p&gt;
&lt;p&gt;This is with clojure.data.xml 0.2.0-alpha6, the latest that I saw on Maven Central; and OpenJDK 11.&lt;/p&gt;
&lt;p&gt;Program:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(set! *warn-on-reflection* true)
(require '[clojure.data.xml :as data.xml])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Reflection warning, clojure/data/xml/jvm/name.clj:35:1 - call to static method decode on java.net.URLDecoder can't be resolved (argument types: unknown, java.lang.String).
Reflection warning, clojure/data/xml/jvm/name.clj:38:1 - call to static method encode on java.net.URLEncoder can't be resolved (argument types: unknown, java.lang.String).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I guess it would be safe and efficient to type-hint the &quot;unknown&quot; first parameter as a String. The URLEncoder/URLDecoder methods in question are overloaded, but the signatures all require a String as the first parameter.&lt;/p&gt;
</description>
<category>data.xml</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11013/reflection-warnings-clojure-data-xml-urlencoder-urldecoder</guid>
<pubDate>Sun, 05 Sep 2021 16:38:10 +0000</pubDate>
</item>
<item>
<title>Possible reflection bug with Abstract Base Class methods not being visible</title>
<link>https://ask.clojure.org/index.php/10029/possible-reflection-abstract-class-methods-being-visible</link>
<description>&lt;p&gt;repro.clj:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn create-application []
  (let [credential (com.microsoft.aad.msal4j.ClientCredentialFactory/createFromSecret &quot;sekrit&quot;)
        builder (com.microsoft.aad.msal4j.ConfidentialClientApplication/builder &quot;client id&quot; credential)
        authority &quot;some authority&quot;]
    (-&amp;gt;
      builder
      (.authority ^String authority)
      (.build))))

(create-application)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;clj -Sdeps '{:deps {com.microsoft.azure/msal4j {:mvn/version &quot;1.8.1&quot;}}}' repro.clj
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The source code for the concrete class is at &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/AzureAD/microsoft-authentication-library-for-java/blob/dev/src/main/java/com/microsoft/aad/msal4j/ConfidentialClientApplication.java&quot;&gt;https://github.com/AzureAD/microsoft-authentication-library-for-java/blob/dev/src/main/java/com/microsoft/aad/msal4j/ConfidentialClientApplication.java&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And the base class is at &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/AzureAD/microsoft-authentication-library-for-java/blob/dev/src/main/java/com/microsoft/aad/msal4j/AbstractClientApplicationBase.java&quot;&gt;https://github.com/AzureAD/microsoft-authentication-library-for-java/blob/dev/src/main/java/com/microsoft/aad/msal4j/AbstractClientApplicationBase.java&lt;/a&gt; where the authority field is declared with a Lombok Accessor annotation...&lt;/p&gt;
</description>
<category>Clojure</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10029/possible-reflection-abstract-class-methods-being-visible</guid>
<pubDate>Fri, 08 Jan 2021 09:00:02 +0000</pubDate>
</item>
<item>
<title>Cannot resolve public generic method from package-private base class</title>
<link>https://ask.clojure.org/index.php/4255/cannot-resolve-public-generic-method-package-private-class</link>
<description>&lt;p&gt;The Clojure compiler cannot resolve a public generic method inherited from a package-private base class.&lt;/p&gt;
&lt;p&gt;Instructions to reproduce:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In package P1&lt;ul&gt;
&lt;li&gt;Define a package-private class A with generic type parameters&lt;/li&gt;
&lt;li&gt;Define a public method M in A using generic types in either its arguments or return value&lt;br&gt;
**** Define a public class B which extends A&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;In package P2&lt;ul&gt;
&lt;li&gt;Construct an instance of B&lt;br&gt;
**** Invoke B.M()&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is valid in Java. In Clojure, invoking B.M produces a reflection warning, followed by the error &quot;java.lang.IllegalArgumentException: Can't call public method of non-public class.&quot; No amount of type-hinting prevents the warning or the error.&lt;/p&gt;
&lt;p&gt;Attachment clj-1243-demo1.tar.gz contains sample code and script to demonstrate the problem.&lt;/p&gt;
&lt;p&gt;Examples of Java projects which use public methods in package-private classes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(link: &lt;a rel=&quot;nofollow&quot; href=&quot;http://netty.io/&quot;&gt;http://netty.io/&lt;/a&gt; text: Netty) 4&lt;ul&gt;
&lt;li&gt;See (link: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/netty/netty/blob/ca0018279754557576bb2ecc17d209c2b6874609/transport/src/main/java/io/netty/bootstrap/AbstractBootstrap.java#L152&quot;&gt;https://github.com/netty/netty/blob/ca0018279754557576bb2ecc17d209c2b6874609/transport/src/main/java/io/netty/bootstrap/AbstractBootstrap.java#L152&lt;/a&gt; text: AbstractBootstrap.java) and (link: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/netty/netty/issues/1780&quot;&gt;https://github.com/netty/netty/issues/1780&lt;/a&gt; text: issue #1780) and Clojure ticket CLJ-1183&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;(link: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/jfager/functional-critbit&quot;&gt;https://github.com/jfager/functional-critbit&lt;/a&gt; text: jfager/functional-critbit)&lt;ul&gt;
&lt;li&gt;See (link: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/jfager/functional-critbit/blob/abb927d7e93ad21eaf75da339c27220f2cfdc222/src/main/java/io/prelink/critbit/AbstractCritBitTree.java#L305&quot;&gt;https://github.com/jfager/functional-critbit/blob/abb927d7e93ad21eaf75da339c27220f2cfdc222/src/main/java/io/prelink/critbit/AbstractCritBitTree.java#L305&lt;/a&gt; text: AbstractCritBitTree.java)&lt;br&gt;
**** Example: {{(.get (io.prelink.critbit.CritBitTree. (org.ardverk.collection.DefaultKeyAnalyzer.)) nil)}}&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>Java Interop</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/4255/cannot-resolve-public-generic-method-package-private-class</guid>
<pubDate>Thu, 01 Aug 2013 19:34:22 +0000</pubDate>
</item>
</channel>
</rss>