Permalink
Browse files

Updated clojure to 1.5.1 and used ddeaguiar's change

ddeaguiar@c74dae0
as a guide.
  • Loading branch information...
rogerallen committed Nov 3, 2013
1 parent 057516a commit 92b805dae1ad4977140ea13259d2fd6be78d90b7
Showing with 58 additions and 54 deletions.
  1. +57 −53 javasrc/cljminecraft/BasePlugin.java
  2. +1 −1 project.clj
@@ -14,44 +14,44 @@
public abstract class BasePlugin extends JavaPlugin{
protected final static String selfPluginName=ClojurePlugin.class.getPackage().getName();//"cljminecraft";
-
+
public final static Charset UTF8 = Charset.forName("UTF-8");
-
+
private final static Logger logger=Bukkit.getLogger();//it would've been the same instance across both main and child plugins
// private final static Logger logger=Logger.getLogger( "Minecraft" );//this is equivalent to above
//true when `reload` happened OR when this plugin got loaded to an already running server ie. via `plugman load pluginnamehere`
private static boolean isServerReloaded=(null != Bukkit.getConsoleSender());
-
+
//true if onEnable was successful, false or null(not found) if onEnable failed or was never executed
private Boolean successfullyEnabled=null;//each plugin will have one of these
-
+
static {//static initializer block
//XXX: on server `reload` this gets re-executed
if ( !isServerReloaded() ) {
boolean asserts = false;
assert ( true == ( asserts = true ) );
-
+
_info( "assertions are " + ( !asserts ? "NOT " : "" ) + "enabled"
+ ( !asserts ? " (to enable pass jvm option -ea when starting bukkit)" : "" ) );
}
-
+
if (isServerReloaded()) {
_info("you just `reload`-ed the server OR this plugin got loaded to an already running server ie. via `plugman load "
+BasePlugin.class.getPackage().getName()+"`");
- //EDIT: there's one variant which may wrongly detect a `reload` if you're using this:
- //if you were running the server then then you just place your plugin in plugins folder and execute a
+ //EDIT: there's one variant which may wrongly detect a `reload` if you're using this:
+ //if you were running the server then then you just place your plugin in plugins folder and execute a
//command something like `plugman load yourplugin` - it will detect it as a reload because getConsoleSender
//is not null at this point. (tested to be true)
- //EDIT2: also note that if the plugin was already running doing `plugman unload it` then `plugman load it`
+ //EDIT2: also note that if the plugin was already running doing `plugman unload it` then `plugman load it`
//(or even `plugman reload it`) won't cause it to be detected as a `reload`
-
+
}
-
+
//this should only be executed for cljminecraft(the main not any children) plugin, and it is so if children have a depend on cljminecraft
//bukkit will then make sure cljminecraft is loaded before them
-
+
//one time in bukkit lifetime(right?) we set *loader* to the classloader which applies to any future clojure scripts loads
ClassLoader previous = Thread.currentThread().getContextClassLoader();
final ClassLoader parentClassLoader = ClojurePlugin.class.getClassLoader();
@@ -69,7 +69,7 @@
_info("!!!!!!!!!!!!!First time clojure init!!");
}
System.out.flush();
-
+
clojure.lang.DynamicClassLoader newCL = (clojure.lang.DynamicClassLoader)AccessController.doPrivileged( new PrivilegedAction() {
@Override
public Object run() {
@@ -79,34 +79,38 @@ public Object run() {
}
} );
assert !clojure.lang.Compiler.LOADER.isBound();//wow this really isn't bound even after `reload` also nothing remains pushed
- clojure.lang.Var.pushThreadBindings( clojure.lang.RT.map( clojure.lang.Compiler.LOADER, newCL) );//so this variant is the one
+ //Addresses NullPointerException with clojure 1.5.
+ //See http://dev.clojure.org/jira/browse/CLJ-1172
+ //Note that there should be a better way to do this...
+ clojure.lang.RT.init();
+ clojure.lang.Var.pushThreadBindings( clojure.lang.RT.map( clojure.lang.Compiler.LOADER, newCL) );//so this variant is the one
// System.err.println(clojure.lang.RT.CLOJURE_NS);
-// clojure.lang.Var.intern(clojure.lang.RT.CLOJURE_NS,//just as I thought this variant won't work
+// clojure.lang.Var.intern(clojure.lang.RT.CLOJURE_NS,//just as I thought this variant won't work
// Symbol.intern("clojure.lang.Compiler/LOADER")//can't intern namespace qualified symbol
//// clojure.lang.Compiler.LOADER.sym this is actually null because there's no counterpart in clojure? :O I thought it was *loader*
// , newCL, true);
// clojure.lang.RT.WARN_ON_REFLECTION;
//XXX: turn on reflection warnings for all plugins (maybe add/override this in each config.yml
//XXX: does the above make sense? not sure how
//no: maybe specify namespace to that *var* - can't intern namespace qualified symbol(I predict)
- clojure.lang.Var.intern(clojure.lang.RT.CLOJURE_NS,
+ clojure.lang.Var.intern(clojure.lang.RT.CLOJURE_NS,
clojure.lang.Symbol.intern("*warn-on-reflection*")
//there's no accessible java field from which to get the symbol directly (they are non-public but there in RT nd Compiler classes)
,
// isServerReloaded()?clojure.lang.RT.T:clojure.lang.RT.F
clojure.lang.RT.F
, true);
//the above is equivalent to clojure code: (set! *warn-on-reflection* true)
-
- clojure.lang.Var.intern(clojure.lang.RT.CLOJURE_NS,
+
+ clojure.lang.Var.intern(clojure.lang.RT.CLOJURE_NS,
clojure.lang.Symbol.intern("*use-context-classloader*")
,clojure.lang.RT.F
, true);
}finally{
Thread.currentThread().setContextClassLoader(previous);
}
}
-
+
/**
* @return true when `reload` happened on server<br>
* OR when this plugin got loaded to an already running server ie. via `plugman load pluginnamehere`
@@ -116,7 +120,7 @@ public final static boolean isServerReloaded() {
//or do we simply give no support for the variant of `plugman load cljminecraft` into an already running server(after just having placed the .jar first time in plugins folder)?
return isServerReloaded;
}
-
+
@Override
public final void onLoad() {
URL jarURL;
@@ -127,40 +131,40 @@ public final void onLoad() {
} catch ( MalformedURLException e ) {
throw new RuntimeException( "should never happen", e );
}
-
+
info( "loaded jar: " + jarURL );
assert clojure.lang.Compiler.LOADER.isBound();
if (!getName().equals(selfPluginName)) {
- //we don't have to add cljminecraft.jar to classpath here
+ //we don't have to add cljminecraft.jar to classpath here
( (clojure.lang.DynamicClassLoader)clojure.lang.Compiler.LOADER.deref() ).addURL( jarURL );
}
}
-
+
public BasePlugin() {
super();
//constructor
info("CONSTRUCTOR");//for "+this.getFile().getAbsoluteFile()); these aren't yet set
//we don't know yet for which plugin we got constructed
- //XXX: an instance is created of this class for every child plugin (including the main one)
+ //XXX: an instance is created of this class for every child plugin (including the main one)
//TODO: maybe add a test to make sure this didn't change in the future
}
-
+
public static String showClassPath(String prefix, ClassLoader cl){
_info("=="+prefix+"== For classloader "+cl+" ----------");
_info(getClassPath(cl));
_info("=="+prefix+"== ----END---"+cl+" ----------");
return "";
}
-
-
+
+
public final static String getClassPath() {
return getClassPath(Thread.currentThread().getContextClassLoader());
}
-
+
public final static String getClassPath(ClassLoader cl) {
URL[] urls = ((URLClassLoader)cl).getURLs();
String cp ="{";
-
+
int max = urls.length-1;
if (max>=0){
cp+=" ";
@@ -182,7 +186,7 @@ public final static String getClassPath(ClassLoader cl) {
cp+="}";
return cp;
}
-
+
protected String showResources(ClassLoader cl, String file1) {
try {
Enumeration<URL> urls = cl.getResources( file1 );
@@ -196,7 +200,7 @@ protected String showResources(ClassLoader cl, String file1) {
}
return "";
}
-
+
protected int count(Enumeration e) {
assert null != e:"you passed null, bug somewhere";
int count=0;
@@ -206,20 +210,20 @@ protected int count(Enumeration e) {
}
return count;
}
-
+
@Override
public InputStream getResource( String fileName ) {
- //XXX: when a file within the .jar of current plugin is needed then from within clojure or java either call this method or call
+ //XXX: when a file within the .jar of current plugin is needed then from within clojure or java either call this method or call
//clojure.lang.RT.getResource(this.getClassLoader(), fileName); where this == plugin instance
//or else it will get the file from cljminecraft not from memorystone, ie. file name like config.yml which exists in both in same location
assert isNotMoreThanOneResource(fileName):"more than 1 file with the same name was detected in classpath,"
+showClassPath("",getClassLoader())
+showResources( getClassLoader(), fileName )
+" PLEASE SEE ABOVE ";
-
+
return super.getResource( fileName );
}
-
+
protected boolean isNotMoreThanOneResource(String fileName) {
try {
return count(getClassLoader().getResources( fileName )) <= 1;
@@ -228,27 +232,27 @@ protected boolean isNotMoreThanOneResource(String fileName) {
throw new RuntimeException(e);
}
}
-
+
public final void severe(String msg) {
info(ChatColor.RED+"[SEVERE] "+ChatColor.RESET+msg);//because colored won't show [SEVERE] only [INFO] level msgs
}
-
+
public final void info(String msg) {
PluginDescriptionFile descFile = getDescription();
String pluginName = this.getClass().getName();
if (null != descFile) pluginName=descFile.getName();
tellConsole(ChatColor.GREEN+"["+pluginName+"]"+ChatColor.RESET+" "+msg);
}
-
+
public static final void _info(String msg) {
info(BasePlugin.class, msg);
}
-
+
public static final void info(Class cls, String msg) {
String className = cls.getName();//we won't know the difference if we're in main or child plugins (cljminecraft or memorystone) because they both use the same main class to start
tellConsole(ChatColor.DARK_AQUA+"["+className+"]"+ChatColor.RESET+" "+msg);//the color is likely never seen due to not inited color console sender
}
-
+
public final static void tellConsole( String msg ) {
// nvm; find another way to display colored msgs in console without having [INFO] prefix
// there's no other way it's done via ColouredConsoleSender of craftbukkit
@@ -260,52 +264,52 @@ public final static void tellConsole( String msg ) {
logger.info(ChatColor.stripColor( msg));
}
}
-
+
public void setSuccessfullyEnabled() {
assert (null == successfullyEnabled) || (false == successfullyEnabled.booleanValue())
:"should not have been already enabled without getting disabled first";
-
+
successfullyEnabled=Boolean.TRUE;
}
-
+
public void removeEnabledState() {
assert ((null == successfullyEnabled) || (true == successfullyEnabled.booleanValue()));
successfullyEnabled=null;
}
-
+
public boolean wasSuccessfullyEnabled() {
return ((null != successfullyEnabled) && (true == successfullyEnabled.booleanValue()));
}
-
+
/**
* if it doesn't return true, then stop() will not be called<br>
* @return true if successfully enabled or false(or thrown exceptions) otherwise<br>
*/
public abstract boolean start();//TODO: rename these or the clojure ones just so it's no confusion when reading code(because they have same name)
-
-
+
+
/**
* called only if start() didn't fail (that is: it returned true and didn't throw exceptions)
- *
+ *
*/
public abstract void stop();
-
+
//synchronized not needed because it's an instance method and each plugin has a different instance
@Override
public final void onEnable() {
assert isEnabled() : "it should be set to enabled before this is called, by bukkit";
-
+
if ( start() ) {
setSuccessfullyEnabled();
}
}
-
-
+
+
@Override
public final void onDisable() {//called only when onEnable didn't fail (if we did the logic right)
assert !isEnabled():"it should be set to disabled before this is called, by bukkit";
-
+
String pluginName = getDescription().getName();
if ( wasSuccessfullyEnabled() ) {
// so it was enabled(successfully prior to this) then we can call to disable it
View
@@ -1,6 +1,6 @@
(defproject cljminecraft "1.0.5-SNAPSHOT"
:description "Clojure for Bukkit Minecraft"
- :dependencies [[org.clojure/clojure "1.4.0"]
+ :dependencies [[org.clojure/clojure "1.5.1"]
[org.clojure/tools.logging "0.2.6"]
[org.clojure/tools.nrepl "0.2.3"]
[org.bukkit/bukkit "1.4.5-R1.0"]

0 comments on commit 92b805d

Please sign in to comment.