testing for a class having been loaded

2016-11-29 Thread Alan Snyder
Prior to JDK 9, it was possible (using setAccessible) to ask a ClassLoader 
whether a class with a given name had been loaded without actually forcing it 
to be loaded.

This hack will not work in JDK9, so I am wondering if there is a way to do this?

If not, can someone explain why it would be a bad thing to be able to do this?

Here is my use case:

I have two classes, A and B, that have been designed to be aware of each other, 
but are packaged in separate JAR files or modules that can be loaded 
independently. My goal is for these classes to make a runtime connection with 
each other, but only if both have been loaded by the application.

If each class can at load (initialization) time test whether the other has been 
loaded, then they can use reflection to make that connection.

All of the other solutions I have thought of require yet a third 
class/interface C that is separately packaged and loaded by both A and B. This 
is feasible, but seems unnecessary.

  Alan



Re: testing for a class having been loaded

2016-11-30 Thread Alan Bateman

On 29/11/2016 21:14, Alan Snyder wrote:


Prior to JDK 9, it was possible (using setAccessible) to ask a ClassLoader 
whether a class with a given name had been loaded without actually forcing it 
to be loaded.

This hack will not work in JDK9, so I am wondering if there is a way to do this?

If not, can someone explain why it would be a bad thing to be able to do this?
I can't quite tell what the hack is, is it reading the private `classes` 
field?




Here is my use case:

I have two classes, A and B, that have been designed to be aware of each other, 
but are packaged in separate JAR files or modules that can be loaded 
independently. My goal is for these classes to make a runtime connection with 
each other, but only if both have been loaded by the application.

If each class can at load (initialization) time test whether the other has been 
loaded, then they can use reflection to make that connection.

All of the other solutions I have thought of require yet a third 
class/interface C that is separately packaged and loaded by both A and B. This 
is feasible, but seems unnecessary.

The scenario sounds like it needs a broker but without specifics then 
it's hard to make suggestions.


One question: Are A and B in different packages? If A is p.A and B is 
q.B when would it be enough to know if any p.* or q.* types have been 
loaded? If so then ClassLoader::getDefinedPackage might be useful.


-Alan


Re: testing for a class having been loaded

2016-11-30 Thread Michael Rasmussen
On 30 November 2016 at 11:46, Alan Bateman  wrote:
> I can't quite tell what the hack is, is it reading the private `classes` 
> field?

I assume reflectively calling ClassLoader::findLoadedClass ?

/Michael


Re: testing for a class having been loaded

2016-11-30 Thread Alan Snyder

> On Nov 30, 2016, at 1:46 AM, Alan Bateman  wrote:
> 
> On 29/11/2016 21:14, Alan Snyder wrote:
> 
>> Prior to JDK 9, it was possible (using setAccessible) to ask a ClassLoader 
>> whether a class with a given name had been loaded without actually forcing 
>> it to be loaded.
>> 
>> This hack will not work in JDK9, so I am wondering if there is a way to do 
>> this?
>> 
>> If not, can someone explain why it would be a bad thing to be able to do 
>> this?
> I can't quite tell what the hack is, is it reading the private `classes` 
> field?
> 


As Michael said, the hack is using reflection with setAccessible() to call the 
protected method ClassLoader::findLoadedClass().

Is there some conceptual or security reason to not provide this functionality 
in a public API?


>> 
>> Here is my use case:
>> 
>> I have two classes, A and B, that have been designed to be aware of each 
>> other, but are packaged in separate JAR files or modules that can be loaded 
>> independently. My goal is for these classes to make a runtime connection 
>> with each other, but only if both have been loaded by the application.
>> 
>> If each class can at load (initialization) time test whether the other has 
>> been loaded, then they can use reflection to make that connection.
>> 
>> All of the other solutions I have thought of require yet a third 
>> class/interface C that is separately packaged and loaded by both A and B. 
>> This is feasible, but seems unnecessary.
>> 
> The scenario sounds like it needs a broker but without specifics then it's 
> hard to make suggestions.
> 
> One question: Are A and B in different packages? If A is p.A and B is q.B 
> when would it be enough to know if any p.* or q.* types have been loaded? If 
> so then ClassLoader::getDefinedPackage might be useful.

ClassLoader::getDefinedPackage might be useful in a new design, especially one 
using modules, as split packages are not allowed.

However, I’m not sure of the implications of this method not searching ancestor 
class loaders. Might there be circumstances where the result is not consistent 
with findLoadedClass()?

  Alan



Re: testing for a class having been loaded

2016-11-30 Thread Alan Bateman

On 30/11/2016 15:51, Alan Snyder wrote:


:
As Michael said, the hack is using reflection with setAccessible() to call the 
protected method ClassLoader::findLoadedClass().

Is there some conceptual or security reason to not provide this functionality 
in a public API?
It's protected because it's for use in class loader implementations. It 
is final so it could potentially be changed to public but would require 
a lot of consideration before going that road. To be honest, the 
scenario is a bit odd, there must be a saner solution that doesn't 
involve checking if classes are loaded.


-Alan


Re: testing for a class having been loaded

2016-11-30 Thread Peter Levart

Hi Alan,

On 11/29/2016 10:14 PM, Alan Snyder wrote:

Prior to JDK 9, it was possible (using setAccessible) to ask a ClassLoader 
whether a class with a given name had been loaded without actually forcing it 
to be loaded.

This hack will not work in JDK9, so I am wondering if there is a way to do this?

If not, can someone explain why it would be a bad thing to be able to do this?

Here is my use case:

I have two classes, A and B, that have been designed to be aware of each other, 
but are packaged in separate JAR files or modules that can be loaded 
independently. My goal is for these classes to make a runtime connection with 
each other, but only if both have been loaded by the application.

If each class can at load (initialization) time test whether the other has been 
loaded, then they can use reflection to make that connection.

All of the other solutions I have thought of require yet a third 
class/interface C that is separately packaged and loaded by both A and B. This 
is feasible, but seems unnecessary.


Why separately packaged? You could do something like the following:


package pkga;

public class ClassA {

public static final class Loaded {
private static boolean loaded;
public static boolean isLoaded() { return loaded; }
}

static {
try {
Class bLoadedClass = Class.forName("pkgb.ClassB$Loaded");
ClassA.class.getModule().addReads(bLoadedClass.getModule());
java.lang.reflect.Method bLoadedMethod = 
bLoadedClass.getMethod("isLoaded");

synchronized (ClassA.Loaded.class) {
ClassA.Loaded.loaded = true;
boolean bLoaded = (Boolean) bLoadedMethod.invoke(null);
if (bLoaded) {
connect();
}
}
} catch (ReflectiveOperationException ignore) {
// ClassB.Loaded not visible
}
}

private static void connect() {
System.out.println("Connecting from A -> B");
}

public static void use() {
System.out.println("A used.");
}
}


package pkgb;

public class ClassB {

public static final class Loaded {
private static boolean loaded;
public static boolean isLoaded() { return loaded; }
}

static {
try {
Class aLoadedClass = Class.forName("pkga.ClassA$Loaded");
ClassB.class.getModule().addReads(aLoadedClass.getModule());
java.lang.reflect.Method aLoadedMethod = 
aLoadedClass.getMethod("isLoaded");

synchronized (aLoadedClass) {
ClassB.Loaded.loaded = true;
boolean aLoaded = (Boolean) aLoadedMethod.invoke(null);
if (aLoaded) {
connect();
}
}
} catch (ReflectiveOperationException ignore) {
// ClassA.Loaded not visible
}
}

private static void connect() {
System.out.println("Connecting from B -> A");
}

public static void use() {
System.out.println("B used.");
}
}




Regards, Peter



Re: testing for a class having been loaded

2016-11-30 Thread Alan Snyder
All questions are worthy of some study, but I’m not getting why you question 
the sanity of asking for the status of classes but have no problem with asking 
for the status of packages.

Do you have some vague sense of possible problems?

  Alan



> On Nov 30, 2016, at 8:45 AM, Alan Bateman  wrote:
> 
> On 30/11/2016 15:51, Alan Snyder wrote:
> 
>> :
>> As Michael said, the hack is using reflection with setAccessible() to call 
>> the protected method ClassLoader::findLoadedClass().
>> 
>> Is there some conceptual or security reason to not provide this 
>> functionality in a public API?
> It's protected because it's for use in class loader implementations. It is 
> final so it could potentially be changed to public but would require a lot of 
> consideration before going that road. To be honest, the scenario is a bit 
> odd, there must be a saner solution that doesn't involve checking if classes 
> are loaded.
> 
> -Alan



Re: testing for a class having been loaded

2016-11-30 Thread Alan Snyder
Why separately packaged? The goal would be loose coupling allowing smaller 
images. Same goal as Jigsaw…

Your solution uses Class.forName(), which will load classes. Perhaps it works, 
but doesn’t it rely on implementation specific behavior for nested static 
classes?

  Alan



> On Nov 30, 2016, at 9:52 AM, Peter Levart  wrote:
> 
> Hi Alan,
> 
> On 11/29/2016 10:14 PM, Alan Snyder wrote:
>> Prior to JDK 9, it was possible (using setAccessible) to ask a ClassLoader 
>> whether a class with a given name had been loaded without actually forcing 
>> it to be loaded.
>> 
>> This hack will not work in JDK9, so I am wondering if there is a way to do 
>> this?
>> 
>> If not, can someone explain why it would be a bad thing to be able to do 
>> this?
>> 
>> Here is my use case:
>> 
>> I have two classes, A and B, that have been designed to be aware of each 
>> other, but are packaged in separate JAR files or modules that can be loaded 
>> independently. My goal is for these classes to make a runtime connection 
>> with each other, but only if both have been loaded by the application.
>> 
>> If each class can at load (initialization) time test whether the other has 
>> been loaded, then they can use reflection to make that connection.
>> 
>> All of the other solutions I have thought of require yet a third 
>> class/interface C that is separately packaged and loaded by both A and B. 
>> This is feasible, but seems unnecessary.
> 
> Why separately packaged? You could do something like the following:
> 
> 
> package pkga;
> 
> public class ClassA {
> 
>public static final class Loaded {
>private static boolean loaded;
>public static boolean isLoaded() { return loaded; }
>}
> 
>static {
>try {
>Class bLoadedClass = Class.forName("pkgb.ClassB$Loaded");
> ClassA.class.getModule().addReads(bLoadedClass.getModule());
>java.lang.reflect.Method bLoadedMethod = 
> bLoadedClass.getMethod("isLoaded");
>synchronized (ClassA.Loaded.class) {
>ClassA.Loaded.loaded = true;
>boolean bLoaded = (Boolean) bLoadedMethod.invoke(null);
>if (bLoaded) {
>connect();
>}
>}
>} catch (ReflectiveOperationException ignore) {
>// ClassB.Loaded not visible
>}
>}
> 
>private static void connect() {
>System.out.println("Connecting from A -> B");
>}
> 
>public static void use() {
>System.out.println("A used.");
>}
> }
> 
> 
> package pkgb;
> 
> public class ClassB {
> 
>public static final class Loaded {
>private static boolean loaded;
>public static boolean isLoaded() { return loaded; }
>}
> 
>static {
>try {
>Class aLoadedClass = Class.forName("pkga.ClassA$Loaded");
> ClassB.class.getModule().addReads(aLoadedClass.getModule());
>java.lang.reflect.Method aLoadedMethod = 
> aLoadedClass.getMethod("isLoaded");
>synchronized (aLoadedClass) {
>ClassB.Loaded.loaded = true;
>boolean aLoaded = (Boolean) aLoadedMethod.invoke(null);
>if (aLoaded) {
>connect();
>}
>}
>} catch (ReflectiveOperationException ignore) {
>// ClassA.Loaded not visible
>}
>}
> 
>private static void connect() {
>System.out.println("Connecting from B -> A");
>}
> 
>public static void use() {
>System.out.println("B used.");
>}
> }
> 
> 
> 
> 
> Regards, Peter



Re: testing for a class having been loaded

2016-11-30 Thread Peter Levart



On 11/30/2016 07:07 PM, Alan Snyder wrote:
Why separately packaged? The goal would be loose coupling allowing 
smaller images. Same goal as Jigsaw…


Your solution uses Class.forName(), which will load classes. Perhaps 
it works, but doesn’t it rely on implementation specific behavior for 
nested static classes?


  Alan


You can create a top-level class if you are worried. You don't even need 
two "Loaded" classes. One "Rendezvous" class is enough. Like this:



package pkga;

public final class Rendezvous {
private static Class aClass, bClass;

static synchronized void aLoaded(Class aCl) {
aClass = aCl;
if (bClass != null) {
connect();
}
}

public static synchronized void bLoaded(Class bCl) {
bClass = bCl;
if (aClass != null) {
connect();
}
}

private static void connect() {
System.out.println("Connecting " + aClass + " with " + bClass);
}
}


package pkga;

public class A {

static {
Rendezvous.aLoaded(A.class);
}

public static void use() {
System.out.println("A used.");
}
}


package pkgb;

public class B {

static {
try {
Class rendezvousClass = Class.forName("pkga.Rendezvous");
B.class.getModule().addReads(rendezvousClass.getModule());
rendezvousClass.getMethod("bLoaded", 
Class.class).invoke(null, B.class);

} catch (ReflectiveOperationException ignore) {
// A$Rendezvous not visible
}
}

public static void use() {
System.out.println("B used.");
}
}


Regards, Peter





On Nov 30, 2016, at 9:52 AM, Peter Levart > wrote:


Hi Alan,

On 11/29/2016 10:14 PM, Alan Snyder wrote:
Prior to JDK 9, it was possible (using setAccessible) to ask a 
ClassLoader whether a class with a given name had been loaded 
without actually forcing it to be loaded.


This hack will not work in JDK9, so I am wondering if there is a way 
to do this?


If not, can someone explain why it would be a bad thing to be able 
to do this?


Here is my use case:

I have two classes, A and B, that have been designed to be aware of 
each other, but are packaged in separate JAR files or modules that 
can be loaded independently. My goal is for these classes to make a 
runtime connection with each other, but only if both have been 
loaded by the application.


If each class can at load (initialization) time test whether the 
other has been loaded, then they can use reflection to make that 
connection.


All of the other solutions I have thought of require yet a third 
class/interface C that is separately packaged and loaded by both A 
and B. This is feasible, but seems unnecessary.


Why separately packaged? You could do something like the following:


package pkga;

public class ClassA {

   public static final class Loaded {
   private static boolean loaded;
   public static boolean isLoaded() { return loaded; }
   }

   static {
   try {
   Class bLoadedClass = Class.forName("pkgb.ClassB$Loaded");
ClassA.class.getModule().addReads(bLoadedClass.getModule());
   java.lang.reflect.Method bLoadedMethod = 
bLoadedClass.getMethod("isLoaded");

   synchronized (ClassA.Loaded.class) {
   ClassA.Loaded.loaded = true;
   boolean bLoaded = (Boolean) bLoadedMethod.invoke(null);
   if (bLoaded) {
   connect();
   }
   }
   } catch (ReflectiveOperationException ignore) {
   // ClassB.Loaded not visible
   }
   }

   private static void connect() {
   System.out.println("Connecting from A -> B");
   }

   public static void use() {
   System.out.println("A used.");
   }
}


package pkgb;

public class ClassB {

   public static final class Loaded {
   private static boolean loaded;
   public static boolean isLoaded() { return loaded; }
   }

   static {
   try {
   Class aLoadedClass = Class.forName("pkga.ClassA$Loaded");
ClassB.class.getModule().addReads(aLoadedClass.getModule());
   java.lang.reflect.Method aLoadedMethod = 
aLoadedClass.getMethod("isLoaded");

   synchronized (aLoadedClass) {
   ClassB.Loaded.loaded = true;
   boolean aLoaded = (Boolean) aLoadedMethod.invoke(null);
   if (aLoaded) {
   connect();
   }
   }
   } catch (ReflectiveOperationException ignore) {
   // ClassA.Loaded not visible
   }
   }

   private static void connect() {
   System.out.println("Connecting from B -> A");
   }

   public static void use() {
   System.out.println("B used.");
   }
}




Regards, Peter






Re: testing for a class having been loaded

2016-11-30 Thread Alan Snyder
By the way, I had no trouble finding examples on the web of using 
findLoadedClass() via reflection. I listed the first 11 below.

Obviously, this hack is known, of interest, and used.

I think it deserves to be an issue.

> As I said, this change will not be popular but please bear with it until the 
> extent of the issues uncovered is more widely understood. We need all the 
> help we can get to identify issues and get them reported (and hopefully 
> fixed) by the libraries and tools with the technical debt (and we expect a 
> lot of it will be technical debt). For those working on OpenJDK and the JDK 9 
> project then it's very possible that some of these issues will redirect to 
> the JDK as requests for new APIs or hooks (and I assume will need to be 
> looked at on a case-by-case basis).
> 
> Any help reporting issues to popular tools and libraries would be appreciated.



https://github.com/HotswapProjects/HotswapAgent/blob/master/hotswap-agent-core/src/main/java/org/hotswap/agent/util/classloader/ClassLoaderHelper.java

http://stackoverflow.com/questions/482633/in-java-is-it-possible-to-know-whether-a-class-has-already-been-loaded

http://stackoverflow.com/questions/12093271/how-do-i-determine-class-loading-order-when-i-inject-them-into-the-systemclasslo

https://dzone.com/articles/classloaderlocal-how-avoid

http://snacktrace.com/artifacts/net.bytebuddy/byte-buddy-dep/1.3.20/net.bytebuddy.dynamic.loading.ClassInjector

https://fossies.org/linux/yacy/source/net/yacy/document/parser/pdfParser.java

http://lists.jboss.org/pipermail/jboss-cvs-commits/2010-May/120099.html

https://devops.ands.org.au/browse/VT-BUILD-55/artifact/JOB1/Javadoc/src-html/au/org/ands/vocabs/toolkit/utils/ApplicationContextListener.html

http://visualvm.sourcearchive.com/documentation/1.2.1-0ubuntu1/ClassLoaderManager_8java-source.html

http://code.taobao.org/svn/QLExpress/trunk/src/main/java/com/ql/util/express/ExpressClassLoader.java

http://svn.rifers.org/rife/tags/release-1.4/src/framework/com/uwyn/rife/engine/EngineClassLoader.java




Re: testing for a class having been loaded

2016-12-06 Thread Alan Snyder
JDK-8170834

> On Nov 30, 2016, at 11:13 AM, Alan Snyder  wrote:
> 
> By the way, I had no trouble finding examples on the web of using 
> findLoadedClass() via reflection. I listed the first 11 below.
> 
> Obviously, this hack is known, of interest, and used.
> 
> I think it deserves to be an issue.
> 
>> As I said, this change will not be popular but please bear with it until the 
>> extent of the issues uncovered is more widely understood. We need all the 
>> help we can get to identify issues and get them reported (and hopefully 
>> fixed) by the libraries and tools with the technical debt (and we expect a 
>> lot of it will be technical debt). For those working on OpenJDK and the JDK 
>> 9 project then it's very possible that some of these issues will redirect to 
>> the JDK as requests for new APIs or hooks (and I assume will need to be 
>> looked at on a case-by-case basis).
>> 
>> Any help reporting issues to popular tools and libraries would be 
>> appreciated.
> 
> 
> 
> https://github.com/HotswapProjects/HotswapAgent/blob/master/hotswap-agent-core/src/main/java/org/hotswap/agent/util/classloader/ClassLoaderHelper.java
> 
> http://stackoverflow.com/questions/482633/in-java-is-it-possible-to-know-whether-a-class-has-already-been-loaded
> 
> http://stackoverflow.com/questions/12093271/how-do-i-determine-class-loading-order-when-i-inject-them-into-the-systemclasslo
> 
> https://dzone.com/articles/classloaderlocal-how-avoid
> 
> http://snacktrace.com/artifacts/net.bytebuddy/byte-buddy-dep/1.3.20/net.bytebuddy.dynamic.loading.ClassInjector
> 
> https://fossies.org/linux/yacy/source/net/yacy/document/parser/pdfParser.java
> 
> http://lists.jboss.org/pipermail/jboss-cvs-commits/2010-May/120099.html
> 
> https://devops.ands.org.au/browse/VT-BUILD-55/artifact/JOB1/Javadoc/src-html/au/org/ands/vocabs/toolkit/utils/ApplicationContextListener.html
> 
> http://visualvm.sourcearchive.com/documentation/1.2.1-0ubuntu1/ClassLoaderManager_8java-source.html
> 
> http://code.taobao.org/svn/QLExpress/trunk/src/main/java/com/ql/util/express/ExpressClassLoader.java
> 
> http://svn.rifers.org/rife/tags/release-1.4/src/framework/com/uwyn/rife/engine/EngineClassLoader.java
> 
>