Getting noClassDefFoundError - noclassdeffounderror

I have a class having static final methods.[Say A,B,C] . C invokes another class D[D's package is imported in C] The maven assembly jar[say M.jar] that i have DOESN'T HAVE package D. During runtime, when i try to call A having M.jar in classpath, getting noclasdef error saying D is not prsent.
Why I am getting this? Please share your thoughts
package TEST1 import test.CHECK.TestA; import test.CHECK.TestB; class Factory
{
final static int A() { //some ref to test.CHECK.TestA }
static int B() { //some ref to test.CHECK.TestB }
static int C() { }
I have jar containing this class and package test.CHECK.TestB in that jar.Howver, this jar doesn't contain test.CHECK.TestA.
Now, my client program having this jar calls c(). Then, getting ClassNotFoundException for TestA, though we are not calling A().Why is this so?

I suppose that you are using Maven, and I supose too that you have two projects.
You have said that in your Jar you have not the testA class, then this class doesn't be added to the classpath and then, the jvm can't locate for use it.
You must consider that any class that you want to use in your application, must be added to the application classpath. This can be added into this Jar, or another Jar, o free, but it must be added.
I hope help you.

Related

NodeEntity not recognized when SessionFactory is created inside library

I am not sure if my problem is a non-existent feature or I am using the neo4j-ogm framework incorrectly. Since you are only supposed to post bugs or feature requests in the projects GitHub repository, I would like to place my question here first.
Please be aware, that I shortened my real code to just give you an idea what I try to achieve.
My example application consists of two modules:
Module a contains a class to create neo4j-ogm sessions. There I read the configuration from a property file and create the session factory, passing the packages to scan as parameters:
public Neo4jController(final String ... packagesWithNodes) {
ConfigurationSource props = new ClasspathConfigurationSource("neo4jogm.properties");
Configuration configuration = new Configuration.Builder(props).build();
SessionFactory sessionFactory = new SessionFactory(configuration, packagesWithNodes);
...
}
Module b includes module a as a Maven dependency and then tries to persist a NodeEntity via the Session object. The Session is created correctly, but the NodeEntity in the passed package is not recognized.
public MyObject create(final MyObject newObject) {
Neo4jController neo4jController = new Neo4jController("my.example.package");
neo4jController.getNeo4jSession().save(newObject);
...
}
This always results in an IllegalArgumentException:
Class class my.example.package.MyObject is not a valid entity class. Please check the entity mapping.
This is what my NodeEntity in module b looks like
package my.example.package;
import de.bitandgo.workflow.common.model.Neo4jNode;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Property;
#NodeEntity(label = "MyObject")
public class MyObject extends Neo4jNode {
#Property
public String name;
}
The base class contains among others
public abstract class Neo4jNode {
#Id
#GeneratedValue
private Long id;
}
I know that neo4j-ogm uses glassgraph internally for scanning the classpath. The corresponding call in the framework with prepended configuration looks like this:
private static List<String> useClassgraph(String[] packagesOrClasses) {
// .enableExternalClasses() is not needed, as the super classes are loaded anywhere when the class is loaded.
try (ScanResult scanResult = new ClassGraph()
.ignoreClassVisibility()
.acceptPackages(packagesOrClasses)
.acceptClasses(packagesOrClasses)
.scan()) {
return scanResult.getAllClasses().getNames();
}
}
Via debugging I verified that the desired package my.example.package was passed as an argument to the GlassGraph object.
Also the Neo4jController in module a is able to load the class. I have tested this with the following code
try {
Class<?> aClass = Class.forName("my.example.package.MyObject");
System.out.println(aClass); // prints "class my.example.package.MyObject"
} catch (ClassNotFoundException e) {}
My question is whether neo4j-ogm/classgraph may not be able to find the class at all due to the way neo4j-ogm uses classgraph, or if I am doing something wrong in the usage.
Update 1:
The problem seems to be related to my application running inside an application server (TomEE). When I deploy my application ClassGraph is not able to find the configured package.
But executing the exact same scan via a classical main method finds me the expected class.
public static void main(String[] args) {
try (ScanResult scanResult = new ClassGraph()
.ignoreClassVisibility()
.acceptPackages("my.example.package")
.acceptClasses()
.scan()) {
System.out.println(scanResult.getAllClasses().getNames());
}
}
So I assume the problem is related to the compiled classes not being visible in the "normal" classpath when deploying the application into an application server?
I appreciate any input.
Thanks a lot
The problem was indeed related to the glassgraph library, which is used by neo4j-ogm for scanning the class path for model files.
glassgraph supports a wide variety of classloaders, but the one of TomEE wasn't included yet. This problem has been fixed since version 4.8.107, so if you run into a similar problem check whether glassgraph supports the classloader of the application server used by you.
You can easily overwrite neo4j-ogm's classgraph dependency by specifying the version you need in your pom.xml.
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-core</artifactId>
<version>${neo4j-version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-bolt-driver</artifactId>
<version>${neo4j-version}</version>
<scope>runtime</scope>
</dependency>
<!-- overwriting the internal classloader of neo4j-ogm because it's used version does not support ApacheTomEE -->
<dependency>
<groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId>
<version>4.8.107</version>
</dependency>
The problem was not related to my multi module Maven structure.

ClassNotFoundException when Loading Custom Class

So there's a lot of questions and examples around of reading external .class files using a ClassLoader but I'm struggling to see where I'm going wrong.
val folderUrl: URL = new File("D:/tmp/").toURI.toURL //file:/D:/tmp/
val cl: URLClassLoader = new URLClassLoader(Array(folderUrl), this.getClass.getClassLoader)
cl.loadClass("my.package.MyClassName")
The last line throws a ClassNotFoundException
The folder D:/tmp/ contains a class file "MyClassName.class".
The class has the package "my.package"
The class is called "MyClassName"
I can't understand what I'm doing wrong?
EDIT:
The two closest question which relate are:
Scala - Dynamic object/class loading
How do I call a Scala Object method using reflection?
But these both do not have my problem however, they both get further than I have done where they successfully load the class before running into issues.
So the issue was the fact that the folder structure did not match the package name.
So my folder structure was
D:/tmp/MyClassName.class
The full class name was
my.package.MyClassName
The class loader requires that the folder structure be
D:/tmp/my/package/MyClassName.class

MEF - Is it possible with directorycatalog to get the latest compiled DLL for the same code?

Let's say I have a contract
public interface IGreeting
{
string SayHelloWorld();
}
And a class in another dll
[Export(typeof(IGreeting))]
public class Greeting : IGreeting
{
public string SayHelloWorld()
{
return "GREETING V1";
}
}
I use directorycatalog to get this DLL. I works fine. When I update my source code like this:
[Export(typeof(IGreeting))]
public class Greeting : IGreeting
{
public string SayHelloWorld()
{
return "GREETING V2";
}
}
and put this new DLL "Next" to the old Greeting DLL Mef doesnt import multiple different Greeting classes but picks 1 out of 2 DLL and exports 2 times from the same class.
So final executing directory looks like this:
MyApp.exe
Greeting_V1.dll
Greeting_V2.dll
I want the application to import 2 Greeting classes with ImportMany. It gives me 2 instances from Greeting_V1.dll. If I delete Greeting_V2.dll it gives me only 1 instance of Greeting_V1.dll.
Well, to me, it looks like you are importing many instances of IGreeting, so in that sense, MEF is doing exactly what it is supposed to do. If you want to replace the instance of Greeting from the V1 assembly with what is in V2, remove the V1 assembly, that way MEF can only load what is available.
It not a MEF problem. The problem is in the loading model of .NET. (or better the way you're objects are loaded by .net)
When MEF loads it returns the correct objects. But when looking for class Greeting when V2 is loaded there is already a Greeting class for V1 dll loaded with the correct class Greeting name for V2 is referring to. And the loader the dll actually referenced by V2 is not loaded.

How to refer to protected inner class in Scala when inheriting from Java (with byte code only)

I am writing a Scala class to inherit from a Java class, and I must override a method that takes a protected Java inner class as a parameter. The Java dependency comes as a jar without source code.
I have the exact same setup as found in https://issues.scala-lang.org/browse/SI-3120 except that I do not have the Java source code available, so scalac only knows about the Java dependency by looking at the byte code (in jar or class files).
This is basically what I'm trying to do:
// javapkg/JavaSuperClass.java
package javapkg;
public class JavaSuperClass {
protected class JavaInnerClass {
}
public void method(JavaInnerClass javaInnerclass) {
System.out.println("hello");
}
}
// scalapkg/ScalaSubClass.scala
package scalapkg
import javapkg.JavaSuperClass
class ScalaSubClass extends JavaSuperClass {
override def method(javaInnerClass: JavaSuperClass#JavaInnerClass) {
println("world")
}
}
I have Java Sun JDK Hotspot 1.6.0_24 and Scala 2.9.0.1 on Linux. This is what happens:
$ cd javapkg
$ javac JavaSuperClass.java
$ cd ../scalapkg
$ scalac -cp .. ScalaSubClass.scala
ScalaSubClass.scala:6: error: class JavaInnerClass in class JavaSuperClass cannot be accessed in javapkg.JavaSuperClass
Access to protected class JavaInnerClass not permitted because
prefix type javapkg.JavaSuperClass does not conform to
class ScalaSubClass in package scalapkg where the access take place
override def method(javaInnerclass: JavaSuperClass#JavaInnerClass) {
^
one error found
Note, if I change JavaSuperClass#JavaInnerClass to simply JavaInnerClass, I get this:
ScalaSubClass.scala:6: error: method method overrides nothing
override def method(javaInnerClass: JavaInnerClass) {
^
one error found
Note: I know this sounds very similar to the common "protected static inner class" Java-compatibility issue in Scala, but I believe this is unrelated because there are no statics anywhere in my example.
I feel like something is wrong, because when I put the same code into a mixed java/scala project in Eclipse, it seemed to compile fine (with the latter JavaInnerClass syntax); it's only when I compile the Scala code with only the Java byte code (and no Java source code) that I cannot get it to work. Am I just completely missing the correct syntax to refer to a Java inner class, is this a known defect, or should I file a compiler bug? I couldn't find anything about this exact use case in my searching.
This is an excellent article that discuss the topic.
EDIT-1
My bad, I answered to quickly. This actually may be a bug Mike, I'm trying to see if I can find a hack around. I'll let you know if I find one.
EDIT-2
I've tried different things but I can't find a way to make it work. Mike I'd suggest you to file a bug report.

Scala 2.12.4: Cannot access protected static Java method from another package anymore

I have java class with protected static method:
package parent;
public class Parent {
protected static void parentMethod() {
System.out.println("I'm in parent static method");
}
}
Before Scala 2.12.4 (2.12.3) I could call this method from another package like this:
package child
import parent.Parent
class Child extends Parent {
def childMethod = {
println("I'm in child method and calling parentMethod")
Parent.parentMethod()
}
}
But Scala 2.12.4 does not compile this code. I'm getting the error:
Error:(9, 12) method parentMethod in object Parent cannot be accessed
in object parent.Parent Access to protected method parentMethod not
permitted because prefix type parent.Parent.type does not conform to
object Child in package child where the access takes place
Parent.parentMethod()
This access pattern was very important for me because JOOQ code generation uses this.
What happened?
Nice catch, this is most likely a regression introduced by this PR, as part of a solution to this issue.
I've already opened a ticket for this that you can track. In the meanwhile, if this kind of access pattern is vital for your application, unfortunately I don't think you have much choice but to stick to Scala 2.12.3 for the time being.
Edit
The issue was already known and a fix has been already merged. As of the time of writing the patch is bound to be part of the 2.12.5 release.