Cannot invoke observeForever on a background thread in React-Native - java

We are trying to integrate a native android framework in react-native using a .aar file. All the steps leading to the integration work fine, i.e. the .aar file gets successfully integrated into the project and the methods are visible throughout the project.
We have completed the steps present at - https://reactnative.dev/docs/native-modules-android
However when we are trying to run some methods that are a part of the .aar framework, we run into an error -
Error: Exception in HostFunction: java.lang.IllegalStateException: Cannot invoke observeForever on a background thread
The code implementation looks like this-
package com.frameworksample;
import static com.facebook.react.bridge.UiThreadUtil.runOnUiThread;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import androidx.annotation.NonNull;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.companyName.sdk.Environment;
import com.companyName.sdk.FrameworkKit;
public class CompanyModule extends ReactContextBaseJavaModule {
CompanyModule(ReactApplicationContext context) {
super(context);
}
#NonNull
#Override
public String getName() {
return "CompanyModule";
}
#ReactMethod
public void logMessage(String name, String message) {
Log.d("Company Module", "Logged a message with the name " + name
+ " and message: " + message);
}
public Runnable initializeSDK(String paramOne, String paramTwo) {
TokenProvider tokenProvider = new TokenProvider();
FrameworkKit.initialise(
this.getReactApplicationContext(),
paramOne,
paramTwo,
tokenProvider,
response -> {
listProfiles();
Log.d("Framework Kit Object", "Object initialized successfully" + response);
return null;
}
);
return null;
}
public Runnable listProfiles() {
Log.d("List profile thread", "" + Thread.currentThread());
FrameworkKit.getInstance().listProfiles("employee#comanpany.com", response -> {
Log.d("List Profiles", "Response - " + response);
return null;
});
return null;
}
#ReactMethod(isBlockingSynchronousMethod = true)
public void initCompanyKit(String paramOne, String paramTwo){
Log.d("init method thread", "" + Thread.currentThread());
runOnUiThread(initializeSDK(paramOne, paramTwo));
}
}
Even though the function listProfiles is running on the main thread, an error is thrown for
Cannot invoke observeForever on a background thread
What can be the reasons for this behaviour and how can we rectify this.

You return null for Runnables, that could be the reason. You can try to return Runnable and override run method of it.
private Runnable initializeSDK(String name) {
return new Runnable() {
#Override
public void run() {
// Your code
}
};
}

Related

Getting partial json response for s3select with aws java sdk v2

I am trying to implement s3select in a spring boot app to query parquet file in s3 bucket, I am only getting partial result from the s3select output, Please help to identify the issue, i have used aws java sdk v2.
Upon checking the json output(printed in the console), overall characters in the output is 65k.
I am using eclipse and tried unchecking "Limit console output" in the console preference, which did not help.
Code is here:-
import java.util.List;
import java.util.concurrent.CompletableFuture;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.core.async.SdkPublisher;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.model.CompressionType;
import software.amazon.awssdk.services.s3.model.EndEvent;
import software.amazon.awssdk.services.s3.model.ExpressionType;
import software.amazon.awssdk.services.s3.model.InputSerialization;
import software.amazon.awssdk.services.s3.model.JSONOutput;
import software.amazon.awssdk.services.s3.model.OutputSerialization;
import software.amazon.awssdk.services.s3.model.ParquetInput;
import software.amazon.awssdk.services.s3.model.RecordsEvent;
import software.amazon.awssdk.services.s3.model.SelectObjectContentEventStream;
import software.amazon.awssdk.services.s3.model.SelectObjectContentEventStream.EventType;
import software.amazon.awssdk.services.s3.model.SelectObjectContentRequest;
import software.amazon.awssdk.services.s3.model.SelectObjectContentResponse;
import software.amazon.awssdk.services.s3.model.SelectObjectContentResponseHandler;
public class ParquetSelect {
private static final String BUCKET_NAME = "<bucket-name>";
private static final String KEY = "<object-key>";
private static final String QUERY = "select * from S3Object s";
public static S3AsyncClient s3;
public static void selectObjectContent() {
Handler handler = new Handler();
SelectQueryWithHandler(handler).join();
RecordsEvent recordsEvent = (RecordsEvent) handler.receivedEvents.stream()
.filter(e -> e.sdkEventType() == EventType.RECORDS)
.findFirst()
.orElse(null);
System.out.println(recordsEvent.payload().asUtf8String());
}
private static CompletableFuture<Void> SelectQueryWithHandler(SelectObjectContentResponseHandler handler) {
InputSerialization inputSerialization = InputSerialization.builder()
.parquet(ParquetInput.builder().build())
.compressionType(CompressionType.NONE)
.build();
OutputSerialization outputSerialization = OutputSerialization.builder()
.json(JSONOutput.builder().build())
.build();
SelectObjectContentRequest select = SelectObjectContentRequest.builder()
.bucket(BUCKET_NAME)
.key(KEY)
.expression(QUERY)
.expressionType(ExpressionType.SQL)
.inputSerialization(inputSerialization)
.outputSerialization(outputSerialization)
.build();
return s3.selectObjectContent(select, handler);
}
private static class Handler implements SelectObjectContentResponseHandler {
private SelectObjectContentResponse response;
private List<SelectObjectContentEventStream> receivedEvents = new ArrayList<>();
private Throwable exception;
#Override
public void responseReceived(SelectObjectContentResponse response) {
this.response = response;
}
#Override
public void onEventStream(SdkPublisher<SelectObjectContentEventStream> publisher) {
publisher.subscribe(receivedEvents::add);
}
#Override
public void exceptionOccurred(Throwable throwable) {
exception = throwable;
}
#Override
public void complete() {
}
}
}
I see you are using selectObjectContent(). Have you tried calling the s3AsyncClient.getObject() method. Does that work for you?
For example, here is a code example that gets a PDF file from an Amazon S3 bucket and write the PDF file to a local file.
package com.example.s3.async;
// snippet-start:[s3.java2.async_stream_ops.complete]
// snippet-start:[s3.java2.async_stream_ops.import]
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
import java.nio.file.Paths;
import java.util.concurrent.CompletableFuture;
// snippet-end:[s3.java2.async_stream_ops.import]
// snippet-start:[s3.java2.async_stream_ops.main]
/**
* Before running this Java V2 code example, set up your development environment, including your credentials.
*
* For more information, see the following documentation topic:
*
* https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
*/
public class S3AsyncStreamOps {
public static void main(String[] args) {
final String usage = "\n" +
"Usage:\n" +
" <bucketName> <objectKey> <path>\n\n" +
"Where:\n" +
" bucketName - The name of the Amazon S3 bucket (for example, bucket1). \n\n" +
" objectKey - The name of the object (for example, book.pdf). \n" +
" path - The local path to the file (for example, C:/AWS/book.pdf). \n" ;
if (args.length != 3) {
System.out.println(usage);
System.exit(1);
}
String bucketName = args[0];
String objectKey = args[1];
String path = args[2];
ProfileCredentialsProvider credentialsProvider = ProfileCredentialsProvider.create();
Region region = Region.US_EAST_1;
S3AsyncClient s3AsyncClient = S3AsyncClient.builder()
.region(region)
.credentialsProvider(credentialsProvider)
.build();
GetObjectRequest objectRequest = GetObjectRequest.builder()
.bucket(bucketName)
.key(objectKey)
.build();
CompletableFuture<GetObjectResponse> futureGet = s3AsyncClient.getObject(objectRequest,
AsyncResponseTransformer.toFile(Paths.get(path)));
futureGet.whenComplete((resp, err) -> {
try {
if (resp != null) {
System.out.println("Object downloaded. Details: "+resp);
} else {
err.printStackTrace();
}
} finally {
// Only close the client when you are completely done with it.
s3AsyncClient.close();
}
});
futureGet.join();
}
}

NI DETECTED ERROR IN APPLICATION: JNI GetMethodID called with pending exception java.lang.RuntimeException

I want to build an app using C++ and Java by JNI in the platform of Qt, I tried to do the code below:
c++
#include "musiclist.h"
#include <QAndroidIntent>
#include <QAndroidJniEnvironment>
#include <QDebug>
#include <QStringList>
#include <QNetworkReply>
MusicTrack::MusicTrack(QObject *parent) : QObject(parent){}
void MusicTrack::testerJava()
{
qDebug()<<"javatest";
QNetworkAccessManager *manager = new QNetworkAccessManager();
//QAndroidJniObject java("org/qtproject/example/musiclist/MusicList");
// jint res = java.callMethod<jint>("createAp","(Landroid/content/Context)I",QtAndroid::androidContext().object());
if (QAndroidJniObject::isClassAvailable("org/qtproject/example/musiclist/MusicList")){
qDebug()<<"Classe trouvé";
QAndroidJniEnvironment env;
jclass javaClass = env.findClass("org/qtproject/example/musiclist/MusicList");
QAndroidJniObject classObject(javaClass);
classObject.callMethod<void>("print",
"(Ljava/lang/String;)V",
"teta");}}
Java Code:
import android.os.Bundle;
import android.widget.TextView;
import android.net.*;
import android.net.wifi.WifiManager;
import android.net.wifi.*;
import android.net.ConnectivityManager;
import android.net.wifi.WifiInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.DhcpInfo;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdManager.DiscoveryListener;
import android.util.Log;
import android.net.nsd.NsdServiceInfo;
import android.text.format.Formatter;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.net.InetAddress;
import java.io.IOException;
import java.net.UnknownHostException;
//import android.app.Activity;
import java.lang.reflect.Method;
public class MusicList extends org.qtproject.qt5.android.bindings.QtActivity {
final String TAG="Display Message";
final String SERVICE_TYPE="_http._tcp.";
final String serviceName= "esp32";
private NsdManager.DiscoveryListener discoveryListener;
private NsdManager nsdManager;
//Context context;
public void initializeDiscoveryListener() {
// Instantiate a new DiscoveryListener
discoveryListener = new NsdManager.DiscoveryListener() {
// Called as soon as service discovery begins.
#Override
public void onDiscoveryStarted(String regType) {
Log.d(TAG, "Service discovery started");
}
#Override
public void onServiceFound(NsdServiceInfo service) {
// A service was found! Do something with it.
Log.d(TAG, "Service discovery success" + service);
if (!service.getServiceType().equals(SERVICE_TYPE)) {
// Service type is the string containing the protocol and
// transport layer for this service.
Log.d(TAG, "Unknown Service Type: " + service.getServiceType());
} else if (service.getServiceName().equals(serviceName)) {
// The name of the service tells the user what they'd be
// connecting to. It could be "Bob's Chat App".
Log.d(TAG, "Same machine: " + serviceName);
} else if (service.getServiceName().contains("NsdChat")){
// nsdManager.resolveService(service, resolveListener);
}
}
#Override
public void onServiceLost(NsdServiceInfo service) {
// When the network service is no longer available.
// Internal bookkeeping code goes here.
Log.e(TAG, "service lost: " + service);
}
#Override
public void onDiscoveryStopped(String serviceType) {
Log.i(TAG, "Discovery stopped: " + serviceType);
}
#Override
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
Log.e(TAG, "Discovery failed: Error code:" + errorCode);
nsdManager.stopServiceDiscovery(this);
}
#Override
public void onStopDiscoveryFailed(String serviceType, int errorCode) {
Log.e(TAG, "Discovery failed: Error code:" + errorCode);
nsdManager.stopServiceDiscovery(this);
}
};
}
public void discover(Context c){
System.out.println("discoverServices");
nsdManager = (NsdManager)c.getSystemService(Context.NSD_SERVICE);
System.out.println("oui");
nsdManager.discoverServices("_http._tcp.", NsdManager.PROTOCOL_DNS_SD, discoveryListener);
System.out.println("oui");
}
//nsdManager = (NsdManager)c.getSystemService(Context.NSD_SERVICE);
public void discoverDevices(Context context)throws IOException {
System.out.println("up");
String re="Abdelhamid";
//System.out.println("up");
initializeDiscoveryListener();
discover(context);
System.out.println("up");
}
public void print(String teta)
{
System.out.println(teta);
}
}
Bu I got the problem below: I thins it's an error complation,
F art : art/runtime/java_vm_ext.cc:410] JNI DETECTED ERROR IN APPLICATION: JNI GetMethodID called with pending exception java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
F art : art/runtime/java_vm_ext.cc:410] at void android.os.Handler.(android.os.Handler$Callback, boolean) (Handler.java:200)
F art : art/runtime/java_vm_ext.cc:410] at void android.os.Handler.() (Handler.java:114)
F art : art/runtime/java_vm_ext.cc:410] at void android.app.Activity.() (Activity.java:865)
F art : art/runtime/java_vm_ext.cc:410] at void org.qtproject.qt5.android.bindings.QtActivity.() (QtActivity.java:94)
First you c code stick is not all, generally reported this error is because you are not in the UI thread operation the UI, but to you here is the print () in Java jni call this part to print a string appears to be no problem, you can check your error this thread elsewhere for operating a part of the UI. Jni error Sometimes the location of the error may not be very accurate.

Websockets Tomcat 7 does not work in existing project

I try to run a websocket server in a Java project that was running on Tomcat6. I have set up a Tomcat 7 server where the project now is running on.
First I tried to run the socket example of Tomcat7. This run perfectly. I copied this class to my old project. When I run the old project again all the functionalities are working like before but only the websocket server doe not work.
This is the ChatAnnotation class that I have copied from the examples from Tomcat to my old project.
import java.io.IOException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.apache.log4j.Logger;
#ServerEndpoint(value = "/websocket/chat")
public class ChatAnnotation {
private static Logger logger = Logger.getLogger(ChatAnnotation.class);
private static final String GUEST_PREFIX = "Guest";
private static final AtomicInteger connectionIds = new AtomicInteger(0);
private static final Set<ChatAnnotation> connections = new CopyOnWriteArraySet<ChatAnnotation>();
private final String nickname;
private Session session;
public ChatAnnotation() {
nickname = GUEST_PREFIX + connectionIds.getAndIncrement();
logger.info("ws instance");
}
#OnOpen
public void start(Session session) {
this.session = session;
connections.add(this);
String message = String.format("* %s %s", nickname, "has joined.");
broadcast(message);
}
#OnClose
public void end() {
connections.remove(this);
String message = String.format("* %s %s", nickname, "has disconnected.");
broadcast(message);
}
#OnMessage
public void incoming(String message) {
// Never trust the client
String filteredMessage = String.format("%s: %s", nickname, message.toString());
broadcast(filteredMessage);
}
#OnError
public void onError(Throwable t) throws Throwable {
logger.error("Chat Error: " + t.toString(), t);
}
private static void broadcast(String msg) {
for (ChatAnnotation client : connections) {
try {
synchronized (client) {
client.session.getBasicRemote().sendText(msg);
}
} catch (IOException e) {
logger.debug("Chat Error: Failed to send message to client", e);
connections.remove(client);
try {
client.session.close();
} catch (IOException e1) {
// Ignore
}
String message = String.format("* %s %s", client.nickname, "has been disconnected.");
broadcast(message);
}
}
}
}
I have noting added in my web.xml. In my old project are also tcpsockets used can this be the problem?
Can anyone help me with this problem?
EDIT
Class added:
import java.util.HashSet;
import java.util.Set;
import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;
import org.apache.log4j.Logger;
public class ExamplesConfig implements ServerApplicationConfig {
private static Logger log = Logger.getLogger(ChatAnnotation.class);
public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> endpointClasses) {
Set<ServerEndpointConfig> result = new HashSet<ServerEndpointConfig>();
log.info("getEndpointConfigs");
return result;
}
public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) {
log.info("getAnnotatedEndpointClasses");
return scanned;
}
}
Java websocket server use return value of ServerApplicationConfig interface to deploy programmatic endpoints and for annotated endpoints.
For Tomcat example, if you change the package name of ChatAnnotation. You have to modify websocket.ExamplesConfig too.
public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) {
// Deploy all WebSocket endpoints defined by annotations in the examples
// web application. Filter out all others to avoid issues when running
// tests on Gump
Set<Class<?>> results = new HashSet<>();
for (Class<?> clazz : scanned) {
String name = clazz.getPackage().getName();
boolean ok = name.startsWith("websocket.");
if (ok) {
results.add(clazz);
}
}
return scanned;
}
The getAnnotatedEndpointClasses(scanned) only return classes which package name start with websocket. Unmatched classes will not deployed even they have #ServerEndpoint declarations.

Using Byte Buddy for Java Agent

I wish to create an agent to attach to our live Tomcat & Weblogic servers which will intercept all method calls to all classes declared in my companies package and do some logging of metrics such as execution time.
I came across the Byte Buddy library which seems to cater for this. However, I am not 100% clear on the approach to creating an agent using Byte Buddy:
The following article suggests that one creates an own agent and makes no mention of the byte-buddy-agent: http://mydailyjava.blogspot.ie/2015/01/make-agents-not-frameworks.html
However, I do see someone has created his/her own byte-buddy-agent so I am
not sure if I am meant to use this.
https://github.com/raphw/byte-buddy/tree/master/byte-buddy-agent
I went with the approach of creating my own agent and packaged it up using Maven to include Byte Buddy as a fat jar (so that the Byte Buddy code is on the class path) which I reference from my catalina.bat.
Edit: I have since downloaded the source and figured out that the AgentBuilder relies on the byte-buddy-agent package so the above question is irrelevant.
Tomcat starts up fine and I can see that the agent is called as I see the "Entered premain" System.out.
However I never see the "Intercepted" System.out when I execute the code on a separate war file deployed to Tomcat.
Edit: Code below updated based on Rafael's response and this is now working.
Can somebody tell me what I might be doing wrong here? I've included the agent code below.
Also, can someone tell me which ElementMatchers is best for package matching? I tried nameStartsWith but it had no effect and the API documentation does not state if it is the fully qualified class name.
*Edit: The nameStartsWith does check the package. *
Anyway, thanks in advance for any help!
package com.mycompany.agent;
import java.lang.instrument.Instrumentation;
import java.util.concurrent.Callable;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
import net.bytebuddy.matcher.ElementMatchers;
public class MyAgent {
public static void premain(String agentArgument, Instrumentation instrumentation) {
System.out.println("Entered premain");
try{
new AgentBuilder.Default()
.withListener( new AgentBuilder.Listener() {
public void onComplete(String arg0) {
System.out.println("Completed - " + arg0);
}
public void onError(String arg0, Throwable arg1) {
System.out.println("Error - " + arg0+", "+arg1.getMessage());
arg1.printStackTrace();
}
public void onIgnored(String arg0) {
System.out.println("Ignored - " + arg0);
}
public void onTransformation(TypeDescription arg0, DynamicType arg1) {
System.out.println("Transformed - " + arg0+", type = "+arg1);
}
})
.rebase(ElementMatchers.nameStartsWith("com.mycompany"))
.transform(new AgentBuilder.Transformer() {
public DynamicType.Builder transform(DynamicType.Builder builder, TypeDescription typeDescription) {
return builder.method(ElementMatchers.any()).intercept(MethodDelegation.to(new Interceptor()));
}
}).installOn(instrumentation);
}
catch (RuntimeException e) {
System.out.println("Exception instrumenting code : "+e);
e.printStackTrace();
}
}
package com.mycompany.agent;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
#SuppressWarnings("rawtypes")
public class Interceptor {
#RuntimeType
public Object intercept( #SuperCall Callable<?> callable, #AllArguments Object[] allArguments, #Origin Method method, #Origin Class clazz) throws Exception {
long startTime = System.currentTimeMillis();
Object response;
try{
response = callable.call();
}
catch(Exception e) {
System.out.println("Exception occurred in method call: " + methodName(clazz, method, allArguments) + " Exception = " + e);
throw e;
}
finally{
System.out.println("Method " + methodName(clazz, method) + " completed in " + (System.currentTimeMillis() - startTime) + " miliseconds");
}
return response;
}
private String methodName(Class clazz, Method method){
return methodName(clazz, method, null);
}
private String methodName(Class clazz, Method method, Object[] allArguments){
StringBuilder builder = new StringBuilder();
builder.append(clazz.getName());
builder.append(".");
builder.append(method.getName());
builder.append("(");
for(int i = 0; i < method.getParameters().length; i++) {
builder.append(method.getParameters()[i].getName());
if(allArguments != null) {
Object arg = allArguments[i];
builder.append("=");
builder.append(arg != null ? arg.toString() : "null");
}
if(i < method.getParameters().length - 1) {
builder.append(", ");
}
}
builder.append(")");
return builder.toString();
}
Everything seems to be right. You should always try registering an AgentBuider.Listener which will expose stack traces of unsuccessful instrumentations if Byte Buddy causes an exception for signaling an illegal instrumentation attempt.
I assume that your class's package-private definition of your Interceptor is the cause of this exception. Your interceptor must be visible to all instrumented code. Otherwise, the class is not invokable.

NullPointerException upon starting my Bukkit plugin

I have been getting the following java.lang.NullPointerException when my plugin is being enabled. I don't really see the problem.
Error:
java.lang.NullPointerException
at tk.mypalsgaming.TARDIScraft.TARDIScraft.onDisable(TARDIScraft.java:31)
at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:219)
at org.bukkit.plugin.java.JavaPluginLoader.disablePlugin(JavaPluginLoader.java:481)
at org.bukkit.plugin.SimplePluginManager.disablePlugin(SimplePluginManager.java:401)
at org.bukkit.plugin.SimplePluginManager.disablePlugins(SimplePluginManager.java:394)
at org.bukkit.craftbukkit.v1_6_R2.CraftServer.disablePlugins(CraftServer.java:281)
at net.minecraft.server.v1_6_R2.MinecraftServer.stop(MinecraftServer.java:349)
at net.minecraft.server.v1_6_R2.MinecraftServer.run(MinecraftServer.java:445)
at net.minecraft.server.v1_6_R2.ThreadServerApplication.run(SourceFile:582)
plugin.yml:
name: TARDIScraft
main: tk.mypalsgaming.TARDIScraft.TARDIScraft
version: 0.0.1
depend: [Vault]
commands:
tardis:
description: TARDIS Command Block and Admin Command
usage: /<command> <TARDIS command> [parameters]
permission: TARDIScraft.admin
permission-message: You are not a TARDIS Admin, so you do not have access to this command.
TARDIScraft.java:
package tk.mypalsgaming.TARDIScraft;
import java.util.logging.Logger;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
public class TARDIScraft extends JavaPlugin {
Logger console = getLogger();
#Override
public void onEnable() {
console.info("Enabling the TARDIS plugin...");
// TODO: onEnable code
}
#Override
public void onDisable() {
console.info("Disabling the TARDIS plugin...");
// TODO: onDisable code
}
public static Permission permission = null;
#SuppressWarnings("unused")
private boolean setupPermissions()
{
RegisteredServiceProvider<Permission> permissionProvider = getServer().getServicesManager().getRegistration(net.milkbowl.vault.permission.Permission.class);
if (permissionProvider != null) {
permission = permissionProvider.getProvider();
}
return (permission != null);
}
public void onPlayerJoin(PlayerJoinEvent evt) {
Player player = evt.getPlayer();
if ( player.hasPermission("TARDIScraft.admin") ) {
console.info("Admin " + player.getName() + " has joined the game.");
}
}
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if ( cmd.getName().equalsIgnoreCase("tardis") ) {
boolean senderIsPlayer;
if ( sender instanceof Player ) {
senderIsPlayer = true;
} else senderIsPlayer = false;
// TODO: tardis Command
if ( args[0].equalsIgnoreCase("admin") ) {
Player playerToAdmin = Bukkit.getPlayer(args[1]);
if ( playerToAdmin != null ) {
permission.playerAdd(playerToAdmin, "TARDIScraft.admin");
}
}
return true;
} else {
return false;
}
}
}
The NullPointerException is from the "getLogger()" call. The parent class "JavaPlugin" has to have initialize() called before the logger exists. Since you are getting the logger at instantiation time rather than after initialize() is called, the parent class returns null.
The documentation suggested simply calling getLogger() inside your onEnable() and onDisable(), likely because initialize() has been called by then.
Note: The source code say to NOT call initialize() yourself!
See:
https://github.com/Bukkit/Bukkit/blob/master/src/main/java/org/bukkit/plugin/java/JavaPlugin.java#L246
http://wiki.bukkit.org/Plugin_Tutorial#Logging_a_message

Categories