Ivan1F
Ivan1F

Reputation: 147

Sending HTTP requests in a Minecraft Mod

I am developing a Fabric Minecraft mod that will send http requests.

Here is the code I used:

import com.google.gson.JsonObject;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;

import java.io.IOException;

public class NetworkUtils {
    public static void post(String url, JsonObject json) throws IOException {
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();

        HttpPost request = new HttpPost(url);
        StringEntity params = new StringEntity(json.toString());
        request.addHeader("content-type", "application/json");
        request.setEntity(params);
        httpClient.execute(request);
        httpClient.close();
    }
}

It worked well when I run it in the development environment. However, when I build it into a jar file and put it in the mods folder of an actual server, it produce the following error:

java.lang.NoClassDefFoundError: org/apache/http/HttpEntity

How can I fix it? Thank you so much if you can help

Upvotes: 0

Views: 2170

Answers (1)

Elikill58
Elikill58

Reputation: 4908

This question contains multiple informations about why you get this error.

When you are in development environment, it's your IDE that run it. So, it will also run all dependencies.

When you build the jar, you don't export dependency.

To do it, you can:

  • For maven, check this or this question:
<dependency>
    <groupId>my.lib</groupId>
    <artifactId>LibName</artifactId>
    <version>1.0.0</version>
    <scope>compile</scope> <!-- here you have to set compile -->
</dependency>

With this part too:

<plugins>
    <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
            <archive>
                <manifest>
                    <mainClass>...</mainClass>
                </manifest>
            </archive>
        </configuration>
        <executions>
            <execution>
                <id>make-assembly</id>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
</plugins>
configurations {
    // configuration that holds jars to include in the jar
    extraLibs
}

dependencies {
    extraLibs 'my.lib:LibName:1.0.0'
}

jar {
    from {
        configurations.extraLibs.collect { it.isDirectory() ? it : zipTree(it) }
    }
}
  • You can load external jar from your own such as explained here :
File file = new File("mylib.jar");
URL url = file.toURI().toURL();

URLClassLoader classLoader = (URLClassLoader)ClassLoader.getSystemClassLoader();
Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
method.setAccessible(true);
method.invoke(classLoader, url);
  • If you are not using one of them, it depend. Sometimes you have an option directly when you export your jar.

Upvotes: 0

Related Questions