Skip to content

Add support for components V2 #2809

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 208 commits into
base: master
Choose a base branch
from

Conversation

freya022
Copy link
Contributor

@freya022 freya022 commented Mar 7, 2025

Pull Request Etiquette

Changes

  • Internal code
  • Library interface (affecting end-user code)
  • Documentation
  • Other: _____

Closes Issue: NaN

Description

This adds the new component system (aka Components V2).

API docs: discord/discord-api-docs#7487
Examples: ComponentsV2Example.java

Make sure to give your opinion on the JDA dev thread.

Supersedes #2806.

Installation (Preview)

You can use the "Using new features" guide from the JDA wiki.

Alternatively, you can get the newest version for your favorite tool, by using the /jitpack pr command in the JDA Discord server. You can use the Update PR button to merge the latest changes if necessary (note that it may not update it if there are conflicts).

image

Migration (Preview)

I've written an OpenRewrite recipe to update most (if not all) breaking changes.

Maintainers note

  • Notify me when you know on which version this will be released on, so I can update and enable the dependency update recipe.
  • The steps will slightly change for the actual release.

Requirements

  • Use a release JDA version (i.e., the group ID must be net.dv8tion)
  • Your current code must compile

Usage

As with any migration tool, it is highly recommended to commit/push your changes before doing anything.

Note: Kotlin 2.X is not supported by OpenRewrite yet, however 1.X should work.

(Kotlin) Gradle
plugins {
    // ...
    id("org.openrewrite.rewrite") version "7.4.1"
}

repositories {
    // ...
    maven("https://jitpack.io")
}

dependencies {
    // Existing JDA dependency
    // ...

    rewrite("io.github.freya022:JDA:{{latest commit hash}}")
    rewrite("org.openrewrite.recipe:rewrite-java-dependencies:1.32.1")
}

rewrite {
    activeRecipe("net.dv8tion.MigrateComponentsV2")
}

Checking changes (dry run)

Run the rewriteDryRun task, this can be done by pressing CTRL twice on IntelliJ then running gradle rewriteDryRun.
This will generate a diff file at build/reports/rewrite/rewrite.patch, you can check the possible changes there.

Applying changes

Run the rewriteRun task.

Maven
  1. Add the following repository:
<repository>
    <id>jitpack</id>
    <url>https://jitpack.io</url>
</repository>
  1. Add the following plugin:
<plugin>
  <groupId>org.openrewrite.maven</groupId>
  <artifactId>rewrite-maven-plugin</artifactId>
  <version>6.6.1</version>
  <configuration>
    <activeRecipes>
      <recipe>net.dv8tion.MigrateComponentsV2</recipe>
    </activeRecipes>
  </configuration>
  <dependencies>
    <dependency>
      <groupId>org.openrewrite.recipe</groupId>
      <artifactId>rewrite-java-dependencies</artifactId>
      <version>1.32.1</version>
    </dependency>
    <dependency>
      <groupId>io.github.freya022</groupId>
      <artifactId>JDA</artifactId>
      <version>{{latest commit hash}}</version>
    </dependency>
  </dependencies>
</plugin>

Checking changes (dry run)

Run the rewrite:dryRun goal, this can be done by pressing CTRL twice on IntelliJ then running mvn rewrite:dryRun.
This will generate a diff file at target/site/rewrite/rewrite.patch, you can check the possible changes there.

Applying changes

Run the rewrite:run goal.

It is recommended to optimize imports (Code | Optimize imports in IntelliJ) after migrating.

@Override
public DataObject toData()
{
final String fileName = Helpers.getLastPathSegment(media.getUrl());
Copy link
Contributor

@MrPowerGamerBR MrPowerGamerBR May 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This causes a NullPointerException when creating a message that has a media gallery item

jda-ktx calls MediaGalleryItem.fromUrl(url), which that calls the MediaGalleryItemImpl(String url) constructor, and the media parameter is set to null

        final String mediaUrl;
        if (this.media != null) {
            final String fileName = Helpers.getLastPathSegment(media.getUrl());
            mediaUrl = "attachment://" + fileName;
        } else {
            mediaUrl = this.url;
        }

        return DataObject.empty()
                .put("media", DataObject.empty().put("url", mediaUrl))
                .put("description", description)
                .put("spoiler", spoiler);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep in mind that there is also other NPE related to the media.getUrl() change, here's another stacktrace

java.lang.NullPointerException: Cannot invoke "net.dv8tion.jda.api.components.ResolvedMedia.getUrl()" because "this.media" is null
	at net.dv8tion.jda.internal.components.mediagallery.MediaGalleryItemImpl.getFiles(MediaGalleryItemImpl.java:98)
	at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:273)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1708)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
	at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:276)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
	at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
	at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1939)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
	at net.dv8tion.jda.api.utils.messages.MessageEditData.getAdditionalFiles(MessageEditData.java:373)
	at net.dv8tion.jda.api.utils.messages.MessageEditData.toData(MessageEditData.java:339)
	at net.dv8tion.jda.internal.requests.restaction.WebhookMessageEditActionImpl.finalizeData(WebhookMessageEditActionImpl.java:56)
	at net.dv8tion.jda.internal.requests.RestActionImpl.submit(RestActionImpl.java:212)
	at net.dv8tion.jda.internal.requests.restaction.TriggerRestAction.submit(TriggerRestAction.java:123)
	at net.dv8tion.jda.api.requests.RestAction.submit(RestAction.java:703)
	at net.perfectdreams.loritta.morenitta.utils.extensions.JDAExtensionsKt.await(JDAExtensions.kt:34)
	at net.perfectdreams.loritta.morenitta.interactions.UnleashedHook$InteractionHook.editOriginal(UnleashedHook.kt:12)
	at net.perfectdreams.loritta.morenitta.interactions.UnleashedHook$InteractionHook.editOriginal(UnleashedHook.kt:15)
	at net.perfectdreams.loritta.morenitta.interactions.vanilla.fun.GiveawayBuilderScreen$Appearance$render$editGiveawayImageButton$1.invokeSuspend(GiveawayBuilderScreen.kt:477)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith$$$capture(ContinuationImpl.kt:33)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:586)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:829)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:717)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:704)
	```

@freya022
Copy link
Contributor Author

freya022 commented May 7, 2025

You're saying you have an issue but didn't describe what the issue is

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants