<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[A Fullstack Blog]]></title><description><![CDATA[A Fullstack Blog]]></description><link>https://dev.noormahal.org</link><generator>RSS for Node</generator><lastBuildDate>Sat, 18 Apr 2026 12:10:07 GMT</lastBuildDate><atom:link href="https://dev.noormahal.org/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[My Experience of Setting up Trixnity Client Dependency in a Kotlin based Android Application Project]]></title><description><![CDATA[Trixnity is a Software Development Kit developed on top of the Matrix Specification for decentralised communication. Trixnity is written in Kotlin and it can be used to add messaging functionality when developing android applications using Kotlin. Th...]]></description><link>https://dev.noormahal.org/my-experience-of-setting-up-trixnity-client-dependency-in-a-kotlin-based-android-application-project</link><guid isPermaLink="true">https://dev.noormahal.org/my-experience-of-setting-up-trixnity-client-dependency-in-a-kotlin-based-android-application-project</guid><category><![CDATA[Trixnity]]></category><category><![CDATA[Kotlin]]></category><category><![CDATA[android app development]]></category><category><![CDATA[Matrix]]></category><dc:creator><![CDATA[Muhammed Salih]]></dc:creator><pubDate>Sun, 09 Mar 2025 19:30:37 GMT</pubDate><content:encoded><![CDATA[<p>Trixnity is a Software Development Kit developed on top of the Matrix Specification for decentralised communication. Trixnity is written in Kotlin and it can be used to add messaging functionality when developing android applications using Kotlin. This article goes over the issues I encountered and fixes I made to solve them while adding Trixnity Client dependency to an Android Studio project.</p>
<p>I am new to Android App development and Kotlin. My wife and I had recently created a project using Android Studio. Messaging capability is needed for the android application we are developing. I was checking out Trixnity for this reason.</p>
<p>I added three Trixnity Client <code>trixnity-client-*</code> artifacts all having version 4.13.2 to our project after which the project was broken. Later I managed to get the project in good condition with the help of documentations online.</p>
<p>Below were the issues I observed while fixing our project setup.</p>
<ol>
<li><p>There was a version conflict in the artifacts of Room Database our project depended on. The project directly depended on a specific version of artifacts for Room Database. Trixnity Client Repository Room internally depended on a different version of Room Database artifacts.</p>
</li>
<li><p>Kotlin Gradle Plugin (KGP) 2.1.0 was required for our project to work after I added the three Trixnity Client artifacts of version 4.13.2. But our project was configured to use KGP 1.9.0.</p>
</li>
<li><p>Our project was configured with Gradle 8.2 and Android Gradle Plugin (AGP) 8.2.1. The version of KGP - 1.9.0 - configured in our project was not compatible with aforementioned Gradle and AGP version according to their officially published compatibility matrix.</p>
</li>
<li><p>Room Database artifacts required KSP instead of KAPT for annotation processing after I upgraded those artifacts for solving issue #1.</p>
</li>
<li><p>Gradle configuration attribute to specify Kotlin Compiler Extension Version became obsolete after I upgraded to KGP version 2.1.0 for solving problem #2 and #3. Official documentation said the Kotlin Compose Plugin had to be applied instead of following the obsolete approach.</p>
</li>
<li><p>Trixnity Client required Ktor engine at runtime. I hadn’t added Ktor engine in our project setup after adding Trixnity Client artifacts.</p>
</li>
<li><p>My attempts to resolve above issues seemingly created inconsistencies in the app installation on my android device used for running the app during development. The app run process from Android Studio was getting stuck with a loading indicator.</p>
</li>
</ol>
<p>Our project got into working condition after fixing above series of issues. Below were the actions I took for fixing our project setup.</p>
<ol>
<li><p>Upgraded version of Room Database artifacts defined in our project to match the version of the same artifacts internally used by Trixnity Client Repository Room.</p>
</li>
<li><p>Upgraded KGP to version 2.1.0 as it was required. Upgraded AGP to version 8.2.2 as it was suggested by Android Studio. Verified that the versions specified for Gradle, AGP and KGP in oir project are compatible according to their compatibility matrix.</p>
</li>
<li><p>Migrated to KSP instead of KAPT for annotation processing.</p>
</li>
<li><p>Applied Kotlin Compose Plugin version 2.1.0</p>
</li>
<li><p>Added Ktor Client OkHttp version 3.1.1. This version of Ktor was chosen because it was the latest version available.</p>
</li>
<li><p>Manually uninstalled the broken app installation from my android device used for running the app during development.</p>
</li>
</ol>
<p>Our project was working fine after making above changes and Trixnity Client became usable. I tested the project setup using my Matrix account on <code>matrix.org</code> public Matrix server. I was able to login to my account programmatically by making use of MatrixClient offered by Trixnity. I was able to pull messages from a Matrix Room to my application’s database and see it in Android Studio’s database inspector.</p>
<p>Snippets from my project setup is attached in the next section of this article. Please keep in mind that the specific actions I took to fix my project setup might not be right for other project setups. My suggestion is to refer official documentation to identify and fix project configuration problems if you are facing any. Links to online sources that helped me to fix my project setup are provided at the end of this article.</p>
<p>Thank you for reading.</p>
<hr />
<h2 id="heading-snippets-from-my-project-setup">Snippets from my Project Setup</h2>
<p>The three Trixnity Client dependencies which I added to module level <code>build.gradle.kts</code></p>
<pre><code class="lang-kotlin">dependencies {
    implementation(<span class="hljs-string">"net.folivo:trixnity-client:4.13.2"</span>)
    implementation(<span class="hljs-string">"net.folivo:trixnity-client-media-okio:4.13.2"</span>)
    implementation(<span class="hljs-string">"net.folivo:trixnity-client-repository-room:4.13.2"</span>)
    ...
</code></pre>
<p>AGP and KGP versions defined in project level <code>build.gradle.kts</code></p>
<pre><code class="lang-kotlin">plugins {
    id(<span class="hljs-string">"com.android.application"</span>) version <span class="hljs-string">"8.2.2"</span> apply <span class="hljs-literal">false</span>
    id(<span class="hljs-string">"org.jetbrains.kotlin.android"</span>) version <span class="hljs-string">"2.1.0"</span> apply <span class="hljs-literal">false</span>
}
</code></pre>
<p>Gradle and AGP version selected in Android Studio Project Structure</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741514589993/b23a002b-133f-4b8f-8917-ab15a306828c.png" alt class="image--center mx-auto" /></p>
<p>KSP Plugin specified in module level <code>build.gradle.kts</code> .</p>
<pre><code class="lang-kotlin">plugins {
    id(<span class="hljs-string">"com.google.devtools.ksp"</span>) version <span class="hljs-string">"2.1.0-1.0.29"</span>
    ...
</code></pre>
<p>Kotlin Compose Plugin specified in module level <code>build.gradle.kts</code></p>
<pre><code class="lang-kotlin">plugins {    
    id(<span class="hljs-string">"org.jetbrains.kotlin.plugin.compose"</span>) version <span class="hljs-string">"2.1.0"</span>
    ...
</code></pre>
<p>Ktor Client OkHttp specified in module level <code>build.gradle.kts</code></p>
<pre><code class="lang-kotlin">dependencies {
    implementation(<span class="hljs-string">"io.ktor:ktor-client-okhttp:3.1.1"</span>)
    ...
</code></pre>
<h2 id="heading-links-to-online-sources-which-were-helpful">Links to Online Sources which were Helpful</h2>
<ul>
<li><p><a target="_blank" href="https://kotlinlang.org/docs/gradle-configure-project.html#apply-the-plugin">https://kotlinlang.org/docs/gradle-configure-project.html#apply-the-plugin</a> - has information regarding gradle project configuration and KGP - AGP - Gradle compatibility matrix.</p>
</li>
<li><p><a target="_blank" href="https://docs.gradle.org/current/userguide/viewing_debugging_dependencies.html">https://docs.gradle.org/current/userguide/viewing_debugging_dependencies.html</a> - has information about inspecting dependency tree in gradle.</p>
</li>
<li><p><a target="_blank" href="https://kotlinlang.org/docs/ksp-quickstart.html#add-a-processor">https://kotlinlang.org/docs/ksp-quickstart.html#add-a-processor</a> - has information about using KSP annotation processor.</p>
</li>
<li><p><a target="_blank" href="https://developer.android.com/jetpack/androidx/releases/compose-kotlin">https://developer.android.com/jetpack/androidx/releases/compose-kotlin</a> - has information about Compose to Kotlin compatibility.</p>
</li>
<li><p><a target="_blank" href="https://ktor.io/docs/client-engines.html">https://ktor.io/docs/client-engines.html</a> - has information about setting up Ktor OkHttp Client Engine.</p>
</li>
<li><p><a target="_blank" href="https://trixnity.gitlab.io/trixnity/docs/start">https://trixnity.gitlab.io/trixnity/docs/start</a> - has information about Trixnity.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[How to start a Confluent Kafka Development Server along with Provectus' Kafka Management Web Interface using a Docker Compose File]]></title><description><![CDATA[Define compose file for kafka coupled with zookeeper. Join them in a docker network element and provide the network a unique name. The name app-network is used in this article. Run this compose file to start Kafka Development Server.
services:
  zook...]]></description><link>https://dev.noormahal.org/how-to-start-a-confluent-kafka-development-server-along-with-provectus-kafka-management-web-interface-using-a-docker-compose-file</link><guid isPermaLink="true">https://dev.noormahal.org/how-to-start-a-confluent-kafka-development-server-along-with-provectus-kafka-management-web-interface-using-a-docker-compose-file</guid><category><![CDATA[kafka]]></category><category><![CDATA[Docker compose]]></category><category><![CDATA[development]]></category><dc:creator><![CDATA[Muhammed Salih]]></dc:creator><pubDate>Tue, 28 May 2024 01:18:43 GMT</pubDate><content:encoded><![CDATA[<p>Define compose file for kafka coupled with zookeeper. Join them in a docker network element and provide the network a unique name. The name <code>app-network</code> is used in this article. Run this compose file to start Kafka Development Server.</p>
<pre><code class="lang-yaml"><span class="hljs-attr">services:</span>
  <span class="hljs-attr">zookeeper:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">confluentinc/cp-zookeeper:7.6.1</span>
    <span class="hljs-attr">container_name:</span> <span class="hljs-string">zookeeper</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">"2181:2181"</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-attr">ZOOKEEPER_CLIENT_PORT:</span> <span class="hljs-number">2181</span>
    <span class="hljs-attr">networks:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">app-network</span>

  <span class="hljs-attr">kafka:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">confluentinc/cp-kafka:7.6.1</span>
    <span class="hljs-attr">container_name:</span> <span class="hljs-string">kafka</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">"9092:9092"</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-attr">KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:</span> <span class="hljs-string">INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT</span>
      <span class="hljs-attr">KAFKA_INTER_BROKER_LISTENER_NAME:</span> <span class="hljs-string">INTERNAL</span>
      <span class="hljs-attr">KAFKA_LISTENERS:</span> <span class="hljs-string">INTERNAL://kafka:29092,EXTERNAL://kafka:9092</span>
      <span class="hljs-attr">KAFKA_ADVERTISED_LISTENERS:</span> <span class="hljs-string">INTERNAL://kafka:29092,EXTERNAL://localhost:9092</span>
      <span class="hljs-attr">KAFKA_ZOOKEEPER_CONNECT:</span> <span class="hljs-string">zookeeper:2181</span>
      <span class="hljs-attr">KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR:</span> <span class="hljs-number">1</span>
    <span class="hljs-attr">depends_on:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">zookeeper</span>
    <span class="hljs-attr">networks:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">app-network</span>

<span class="hljs-attr">networks:</span>
  <span class="hljs-attr">app-network:</span>
    <span class="hljs-attr">name:</span> <span class="hljs-string">app-network</span>
    <span class="hljs-attr">driver:</span> <span class="hljs-string">bridge</span>
</code></pre>
<p>List networks managed by docker engine. Ensure that the network you have defined is listed.</p>
<pre><code class="lang-plaintext">C:\some\path&gt;podman network ls
NETWORK ID    NAME                              DRIVER
ba0ccfa0295b  app-network                       bridge
</code></pre>
<p>Define another compose file for kafka-ui. Specify the network you have defined earlier as an external network here and join kafka-ui service with it. Run this compose file to start Provectus' Kafka Management Web Interface.</p>
<pre><code class="lang-yaml"><span class="hljs-attr">services:</span>
  <span class="hljs-attr">kafka-ui:</span>
    <span class="hljs-attr">container_name:</span> <span class="hljs-string">kafka-ui</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">provectuslabs/kafka-ui:v0.7.2</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-number">8080</span><span class="hljs-string">:8080</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-attr">DYNAMIC_CONFIG_ENABLED:</span> <span class="hljs-string">'true'</span>
      <span class="hljs-attr">KAFKA_CLUSTERS_0_NAME:</span> <span class="hljs-string">local</span>
      <span class="hljs-attr">KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS:</span> <span class="hljs-string">kafka:29092</span>
    <span class="hljs-attr">networks:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">app-network</span>

<span class="hljs-attr">networks:</span>
    <span class="hljs-attr">app-network:</span>
        <span class="hljs-attr">name:</span> <span class="hljs-string">app-network</span>
        <span class="hljs-attr">external:</span> <span class="hljs-literal">true</span>
</code></pre>
<p>Done!</p>
<p>Kafka listener will be accessible on host machine at <code>localhost:9092</code> and this address must be used as bootstrap server(s) for your application running in host machine. Web interface to manage kafka will be accessible from web browser at <code>localhost:8080</code> .</p>
<h2 id="heading-footnotes">Footnotes</h2>
<p>At the time of writing this article, I have used Compose V2 specification to define compose files and Podman v5.0.1 to run compose files. A desktop running Windows 11 was used as host machine.</p>
<h3 id="heading-references">References</h3>
<ul>
<li><p><a target="_blank" href="https://www.confluent.io/blog/kafka-listeners-explained/">https://www.confluent.io/blog/kafka-listeners-explained/</a></p>
</li>
<li><p><a target="_blank" href="https://docs.docker.com/compose/compose-file/06-networks/">Networks top-level elements | Docker Docs</a></p>
</li>
</ul>
]]></content:encoded></item></channel></rss>