Fork me on GitHub
#clojure-dev
<
2019-02-21
>
dominicm12:02:36

I'm seeing a case where clojure.core is loaded twice. I think it's because my class loader is reporting 0 for "getLastModified". Normally, https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L444-L447 is true, which goes down into loadClassForName which eventually checks whether the class is already loaded or not before actually loading it. Because my getLastModified is 0 though, I end up in if(!loaded && cljURL != null) { which has no conditional to it's loading, it just unconditionally loads it. Should that second path be looking at whether the class is already loaded before running? Or perhaps should loaded default to a check, rather than false?

dominicm12:02:09

alternatively, instead of lastModified > lastModified, you could do lastModified >= lastModified, but I don't actually know the repercussions of that.

Alex Miller (Clojure team)13:02:49

I think you should back up and consider that the classloader is telling you the wrong value for lastModified. Isn’t this exactly the onejar ticket you linked to?

dominicm13:02:42

The lastModified was null in the ticket I think, and it was fixed by changing to something which returns 0

Alex Miller (Clojure team)13:02:47

Why can’t onejar actually retain the real time stamps? The issue being that you want class time stamps newer than clj timestamps

dominicm13:02:52

Yeah, that's a good question, and not one I have an answer to.

dominicm13:02:53

I would guess that it is trying to avoid unzipping the jars maybe, or it is just naïve.

dominicm13:02:08

I could do some hacking on onejar perhaps.

Alex Miller (Clojure team)13:02:08

The info is in the inner jar, doesn’t seem like there’s any reason you couldn’t use it

dominicm15:02:46

I'm trying to figure out where this is going wrong. It is just delegating upwards, so I'm trying to figure out if I can override the method to check inside the jar, the internal interface isn't too clear

dominicm15:02:40

I think it's something to do with OneJar's use of a byte cache.

dominicm15:02:01

Anyway, it's perfectly normal for a URLConnection to return 0: https://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html#getLastModified() It's a special case defined.

Alex Miller (Clojure team)16:02:58

clojure is a published artifact with different class and clj files in it and they have different timestamps, and that's important to Clojure

Alex Miller (Clojure team)16:02:38

so regardless whether 0 is a valid value for the method, it's yielding a different environment

Alex Miller (Clojure team)16:02:48

I'm still of the opinion that's on onejar, not on Clojure

dominicm17:02:52

I have a patch to the vendored onejar which is doing the trick to expose the last modified

seancorfield17:02:45

One of the bugs I fixed in depstar was that it didn't preserve timestamps when creating the JAR file and that bit me quite badly until I figured out the problem. Hence, we use my fork of depstar at work.

dominicm18:02:33

Latest version of pack has a patch to onejar to override the getLastModified. For the most part, pack avoids the last modified problem inherently, as it doesn't explode any jars.

dominicm18:02:06

But onejar was caching bytes for classes, and creating ByteArrayOutputStreams, which when proxied through the URLConnection didn't have LastModified information attached.