I am trying to programatically add a jar file (that is not on the class path) into code running on a jee app server, and to scan the entity for annotated classes, and then add the classes found to my Ejb3Configuration using .addAnnotatedClasses(myEntityClass).
It is almost working, but I've been stumped several days now, with some kind of class loading issue.
Here is my code:
//...unrelated code above URLClassLoader loader = getURLClassLoader(jarPath); /* ClassLoader conextClassLoader = Thread.currentThread().getContextClassLoader(); URL entryURL = conextClassLoader.getResource(jarPath); if (entryURL == null) { throw new Exception("URL is null for jarPath: " + jarPath); } JarVisitor j = JarVisitorFactory.getVisitor(Thread.currentThread() .getContextClassLoader().getResource(jarPath), filters); */ JarVisitor j = JarVisitorFactory.getVisitor(jarPath, filters); Set<Entry>[] entries = (Set<Entry>[]) j.getMatchingEntries(); for (int i = 0; i < entries.length; i++) { for (Entry c : entries[i]) { try { Class<?> entityClass = Class.forName(c.getName(), false, loader); hibernateEjbConfiguration.addAnnotatedClass(entityClass); } catch (Exception e) { Logger.getLogger(DynamicPU.class.getName()).log(Level.SEVERE, null, e); } } }
Iterator<PersistentClass> it = hibernateEjbConfiguration.getClassMappings(); if (!it.hasNext()) { throw new Exception("No class mappings have been added to the Ejb3Configuration"); }
// ....unrelated code below
Here is what happens when I run it: 1) If I use the code (commented out above, but seems to be the way other are doing this) where the JarVisitor uses a URL derived from the current threads context classloader, the resulting URL is always null. My jarPath=/D:/EJB_Module_2.jar and I have also tried D:/EJB_Module_2.jar and //D:/EJB_Module_2.jar. So I could never get that code to work.
2) But if I just use the code above (passing the JarVisitorFactory my jarPath (an absolute path) string ) the JarVisitor loads my jar and correctly identifies the annotated entity classes it contains. So far so good then.
3) The next step is to instantiate a class instances for each of these Entities and add them to my configuration in the line: hibernateEjbConfiguration.addAnnotatedClass(entityClass);
=> I have found unless I build my own URLClassLoader and pass it to the method Class.forName(... , then I can not instantiate the class) => But when I call addAnnotatedClass(entityClass), while no exceptions or log warnings are generated, the resulting configuration has no mapped classes in it
One other bit of info: if I put this jar at jarPath in my classpath at deployment, everything works fine without any custom classloading. (By works fine I mean that I get an ejb3configuration that has the expected mappings of my entity classes in it).
And keep in mind this code is running on a JEE server (gfv2). Any insights/thoughts/advice are MUCH appreciated
|