armedbear / abcl

Armed Bear Common Lisp <git+https://github.com/armedbear/abcl/> <--> <svn+https://abcl.org/svn> Bridge
https://abcl.org#rdfs:seeAlso<https://gitlab.common-lisp.net/abcl/abcl>
Other
292 stars 30 forks source link

can't instantiate class #376

Open justin2004 opened 3 years ago

justin2004 commented 3 years ago

while attempting to instantiate the the primary class from this repo: https://github.com/LinuxForHealth/hl7v2-fhir-converter i noticed that ABCL runs into trouble.

without ABCL we can instantiate the class:

justin@parens:/tmp/one$ tar -xaf example.tar.gz
justin@parens:/tmp/one$ cat Some.java
public class Some{
    public static void main(String[] args){
        io.github.linuxforhealth.hl7.HL7ToFHIRConverter o = new io.github.linuxforhealth.hl7.HL7ToFHIRConverter();
        System.out.println("here: " + o);
    }
}
justin@parens:/tmp/one$ javac Some.java
justin@parens:/tmp/one$ java -cp `pwd`:shared-things-1.0.0-jar-with-dependencies.jar Some > out.txt 2>&1
justin@parens:/tmp/one$ tail -3 out.txt
May 11, 2021 6:50:00 PM com.ibm.fhir.registry.util.FHIRRegistryUtil readIndex
INFO: Loading index: hl7/fhir/core/package/.index.json
here: io.github.linuxforhealth.hl7.HL7ToFHIRConverter@1a531422
justin@parens:/tmp/one$ java -version
openjdk version "11.0.7" 2020-04-14
OpenJDK Runtime Environment (build 11.0.7+10-post-Ubuntu-2ubuntu219.10)
OpenJDK 64-Bit Server VM (build 11.0.7+10-post-Ubuntu-2ubuntu219.10, mixed mode, sharing)
justin@parens:/tmp/one$

with ABCL 1.8.0 we can't instantiate it:

CL-USER> (require :abcl-contrib)
NIL
CL-USER> (require :jss)
NIL
CL-USER> (java:add-to-classpath "/mnt/shared-things-1.0.0-jar-with-dependencies.jar")
T
CL-USER> (java:add-to-classpath "/mnt/")
T
CL-USER> (java:dump-classpath)
((#<org.armedbear.lisp.JavaClassLoader org.armedbear.lisp.JavaClassLoad.... {7CD82EE9}> #P"file:///mnt/shared-things-1.0.0-jar-with-dependencies.jar" #P"file:///mnt/") #<jdk.internal.loader.ClassLoaders$AppClassLoader jdk.internal.loader.ClassLoaders.... {3A594FF7}> #<jdk.internal.loader.ClassLoaders$PlatformClassLoader jdk.internal.loader.ClassLoaders.... {5618AE27}>)
CL-USER> (jss:japropos "hl7tofhir")
io.github.linuxforhealth.hl7.HL7ToFHIRConverter: Java Class
NIL
CL-USER> (jss:new "io.github.linuxforhealth.hl7.HL7ToFHIRConverter")
Java exception 'org.apache.commons.configuration2.ex.ConfigurationRuntimeException: java.lang.ClassNotFoundException: org.apache.commons.configuration2.PropertiesConfiguration'.
   [Condition of type JAVA-EXCEPTION]
; Evaluation aborted on NIL
CL-USER> ; Quit to level 1
CL-USER> ; Evaluation aborted on #<JAVA-EXCEPTION org.apache.commons.configuration2.ex.ConfigurationRuntimeException: java.lang.ClassNotFoundException: org.apache.commons.configuration2.PropertiesConfiguration {7CDF7BFA}>
; but notice that class is on the classpath and we can instantiate it directly:
CL-USER> (jss:new "org.apache.commons.configuration2.PropertiesConfiguration")
#<org.apache.commons.configuration2.PropertiesConfiguration org.apache.commons.configuration.... {311B74D7}>
CL-USER> 

i'll attach the tar.gz file.

justin2004 commented 3 years ago

example.tar.gz:

https://drive.google.com/file/d/1G9JVg7NC3qvD66b-8-o_4L_-omsg4mla/view?usp=sharing

justin2004 commented 3 years ago

using the same example.tar.gz file i am able to instantiate that class with clojure. so i think that tells us there is something about ABCL's classloader that is having trouble.

project.clj

(defproject hl7 "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
            :url "https://www.eclipse.org/legal/epl-2.0/"}
  :dependencies [[org.clojure/clojure "1.10.0"]
                 [org.clojure/java.classpath "1.0.0"]]
  :resource-paths ["shared-things-1.0.0-jar-with-dependencies.jar" "."]
  :repl-options {:init-ns hl7.core})
(ns hl7.core)
(new io.github.linuxforhealth.hl7.HL7ToFHIRConverter)
> #object[io.github.linuxforhealth.hl7.HL7ToFHIRConverter 0x167b4a07 "io.github.linuxforhealth.hl7.HL7ToFHIRConverter@167b4a07"]
easye commented 3 years ago

I believe you don't have all the dependencies correctly assembled in "shared-things-1.0.0-jar-with-dependencies.jar".

When I build the jar from https://github.com/LinuxForHealth/hl7v2-fhir-converter, and try to instantiate the

CL-USER> (java:add-to-classpath "/home/mevenson/work/hl7v2-fhir-converter/build/libs/hl7v2-fhir-converter-1.0.1-SNAPSHOT.jar                                
T                                                                                                                                                           
CL-USER> (jss:new "io.github.linuxforhealth.hl7.HL7ToFHIRConverter")                                                                                        
; Evaluation aborted on #<JAVA-EXCEPTION java.lang.NoClassDefFoundError: ca/uhn/hl7v2/HL7Exception {14A98F82}>.  

which is telling me I don't have all the necessary runtime dependencies to instantiate this class, as it depends in the presence of ca.uhn.hl7v2.HL7Exception.

I tried downloading the necessary artifacts from Maven, but the dependency chain fails with errors in finding com.ibm.fhir:fhir-term.jar:4.4.0

If you can give me a simple, reproducible recipe for assembling the artifacts necessary to run this thing, perhaps via Maven coordinates that actually resolve, perhaps I can help you further.

I see no evidence that the ABCL classloader is broken, more that it isn't easy to get a handle on the necessary dependencies to instantiate this class.

justin2004 commented 3 years ago

I believe you don't have all the dependencies correctly assembled in "shared-things-1.0.0-jar-with-dependencies.jar".

correct. which is why i included a tar.gz file which includes a directory called "io" which has the correct path structure and .class files necessary to instantiate io.github.linuxforhealth.hl7.HL7ToFHIRConverter. and then i add the pwd to the classpath so that ./io/github/linuxforhealth/hl7/HL7ToFHIRConverter.class, for example, exists.

the combination of shared-things-1.0.0-jar-with-dependencies.jar and the "io" subdirectory on the classpath are necessary.

my pwd was /mnt so i did

(java:add-to-classpath "/mnt/")
justin2004 commented 3 years ago

also there are a few other files in the tar.gz that are needed to successfully instantiate that class. e.g. config.properties

and i was able to instantiate that class by extracting the contents in my pwd (not with ABCL, however).

justin2004 commented 3 years ago

@easye i think the bug might be due to the particular way that some .class files are in a jar and some are in the filesystem. do you want me to package this example up in a different way?

easye commented 3 years ago

@easye do you want me to package this example up in a different way?

Yes, I would like you to try to distill the simplest case of your problem. I really don't want to download 106 Mib of unreproducible artifacts jar'd together: it tells me virtually nothing, other than there is some nightmare Java dependency hell being slopped together without understanding in the hopes that something might just work if we add this…

If you believe that it is a problem with .class files in a jar, and some on the filesystem, why not make the simplest possible test case that fails. Is one class in the jar sufficient to make things fail? Then provide that jar. And so on.