diff --git a/collects/scribble/jfp/.gitignore b/collects/scribble/jfp/.gitignore
new file mode 100644
index 00000000..d5788f43
--- /dev/null
+++ b/collects/scribble/jfp/.gitignore
@@ -0,0 +1,2 @@
+# to avoid committing it by accident, since we can't distribute it
+/jfp1.cls
diff --git a/collects/scribble/jfp/lang.rkt b/collects/scribble/jfp/lang.rkt
index 460520a2..9ea1d97c 100644
--- a/collects/scribble/jfp/lang.rkt
+++ b/collects/scribble/jfp/lang.rkt
@@ -4,7 +4,9 @@
          (except-in scribble/base author)
          scribble/decode
          scribble/jfp
+         setup/main-collects
          "../private/defaults.rkt"
+         net/ftp
          (for-syntax scheme/base))
 (provide (except-out (all-from-out scribble/doclang) #%module-begin)
          (all-from-out scribble/jfp)
@@ -22,10 +24,29 @@
     [(_ id . body)
      #'(#%module-begin id (post-process) () . body)]))
 
+(define cls-file
+  (let ([p (scribble-file "jfp/jfp1.cls")])
+    (if (file-exists? (main-collects-relative->path p))
+        p
+        (downloaded-file "jfp1.cls"))))
+
 (define ((post-process) doc)
   (add-defaults doc
                 (string->bytes/utf-8
-                 (format "\\documentclass{jfp}\n\\usepackage{times}\n\\usepackage{qcourier}\n"))
+                 (format "\\documentclass{jfp1}\n\\usepackage{times}\n\\usepackage{qcourier}\n"))
                 (scribble-file "jfp/style.tex")
-                (list (scribble-file "jfp/jfp.cls"))
+                (list cls-file)
                 #f))
+
+(unless (or (not (path? cls-file))
+            (file-exists? cls-file))
+  (log-error (format "File not found: ~a" cls-file))
+  (define site "ftp.cambridge.org")
+  (define path "pub/texarchive/journals/latex/jfp-cls")
+  (define file "jfp1.cls")
+  (log-error (format "Downloading via ftp://~a/~a/~a..." site path file))
+  (define c (ftp-establish-connection site 21 "anonymous" "user@racket-lang.org"))
+  (ftp-cd c path)
+  (let-values ([(base name dir?) (split-path cls-file)])
+    (ftp-download-file c base file))
+  (ftp-close-connection c))
diff --git a/collects/scribble/lncs/lang.rkt b/collects/scribble/lncs/lang.rkt
index ed0f9965..c65b8f74 100644
--- a/collects/scribble/lncs/lang.rkt
+++ b/collects/scribble/lncs/lang.rkt
@@ -10,6 +10,8 @@
          scribble/html-properties
          scribble/latex-properties
          racket/stxparam
+         net/ftp
+         file/gunzip
          (for-syntax racket/stxparam-exptime 
                      racket/base
                      setup/dirs))
@@ -23,17 +25,6 @@
          email)
 
 (define-syntax (module-begin stx)
-  (unless (file-exists? (collection-file-path "llncs.cls" "scribble" "lncs"))
-    (define cd (find-collects-dir))
-    (raise-syntax-error 'scribble/lncs
-                        (format "Please download the llncs.cls file (in llncs2e.zip) and put it in this directory:\n  ~a~a"
-                                (build-path (find-user-collects-dir)
-                                            "scribble" "lncs")
-                                (if cd
-                                    (format "\nor in this one:\n  ~a"
-                                            (build-path cd "scribble" "lncs"))
-                                    ""))
-                        #f))
   ;; No options, currently, but keep in case we want to support some:
   (syntax-case* stx () (lambda (a b) (eq? (syntax-e a) (syntax-e b)))
     [(_ id ws . body)
@@ -44,11 +35,17 @@
     [(_ id . body)
      #'(#%module-begin id (post-process) () . body)]))
 
+(define cls-file
+  (let ([p (scribble-file "lncs/llncs.cls")])
+    (if (file-exists? (main-collects-relative->path p))
+        p
+        (downloaded-file "llncs.cls"))))
+
 (define ((post-process) doc)
   (add-defaults doc
                 (string->bytes/utf-8 "\\documentclass{llncs}\n") 
                 (scribble-file "lncs/style.tex")
-                (list (scribble-file "lncs/llncs.cls"))
+                (list cls-file)
                 #f))
 
 (define lncs-extras
@@ -59,6 +56,52 @@
      (make-css-addition (abs "lncs.css"))
      (make-tex-addition (abs "lncs.tex")))))
 
+(unless (or (not (path? cls-file))
+            (file-exists? cls-file))
+  (log-error (format "File not found: ~a" cls-file))
+  (define site "ftp.springer.de")
+  (define path "pub/tex/latex/llncs/latex2e")
+  (define file "llncs2e.zip")
+  (log-error (format "Downloading via ftp://~a/~a/~a..." site path file))
+  (define c (ftp-establish-connection site 21 "anonymous" "user@racket-lang.org"))
+  (ftp-cd c path)
+  (ftp-download-file c (find-system-path 'temp-dir) file)
+  (ftp-close-connection c)
+  (define z (build-path (find-system-path 'temp-dir) file))
+  ;; Poor man's unzip (replace it when we have an `unzip' library):
+  (define i (open-input-file z))
+  (define (skip n) (file-position i (+ (file-position i) n)))
+  (define (get n) 
+    (define s (read-bytes n i))
+    (unless (and (bytes? s) (= n (bytes-length s)))
+      (error "unexpected end of file"))
+    s)
+  (let loop ()
+    (cond
+     [(equal? #"PK\3\4" (get 4))
+      ;; local file header
+      (skip 2)
+      (define data-desc? (bitwise-bit-set? (bytes-ref (get 1) 0) 3))
+      (skip 11)
+      (define sz (integer-bytes->integer (get 4) #f #f))
+      (skip 4)
+      (define name-sz (integer-bytes->integer (get 2) #f #f))
+      (define extra-sz (integer-bytes->integer (get 2) #f #f))
+      (define name (bytes->string/utf-8 (get name-sz) #\?))
+      (skip extra-sz)
+      (if (equal? name "llncs.cls")
+          (call-with-output-file cls-file
+            (lambda (o)
+              (inflate i o)))
+          (begin
+            (skip sz)
+            (when data-desc?
+              skip 12)
+            (loop)))]
+     [else (error "didn't find file in archive")]))
+  (close-input-port i)
+  (delete-file z))
+
 ;; ----------------------------------------
 ;; Abstracts:
 
@@ -110,7 +153,6 @@
     [(_ . rest)
      (raise-syntax-error 'authors "expected a sequence of authors" stx)]))
 
-
 (define-syntax-parameter email-ok #f)
 
 (define-syntax (institute stx)
diff --git a/collects/scribble/private/defaults.rkt b/collects/scribble/private/defaults.rkt
index 05393d86..b95b0149 100644
--- a/collects/scribble/private/defaults.rkt
+++ b/collects/scribble/private/defaults.rkt
@@ -4,6 +4,7 @@
          setup/main-collects)
 
 (provide scribble-file
+         downloaded-file
          add-defaults)
 
 (define (add-property properties pred new)
@@ -14,6 +15,9 @@
 (define (scribble-file s)
   (path->main-collects-relative (collection-file-path s "scribble")))
 
+(define (downloaded-file s)
+  (build-path (find-system-path 'addon-dir) s))
+
 (define (add-defaults doc pfx styl extras version?)
   (struct-copy part doc [style (make-style (style-name (part-style doc))
                                            ((if version? add-property (lambda (x y z) x))
diff --git a/collects/scribblings/scribble/jfp.scrbl b/collects/scribblings/scribble/jfp.scrbl
index b833fce9..ec94a5bc 100644
--- a/collects/scribblings/scribble/jfp.scrbl
+++ b/collects/scribblings/scribble/jfp.scrbl
@@ -11,8 +11,11 @@
 
 @defmodulelang[scribble/jfp]{The @racketmodname[scribble/jfp]
 language is like @racketmodname[scribble/manual], but configured with
-Latex style defaults to use the @filepath{jfp.cls} class
-file that is included with Scribble.}
+Latex style defaults to use the @filepath{jfp1.cls} class
+file. The class file is not included with Scribble due to license
+issues, but if the file is not manually installed into the
+@racket[scribble/jfp] collections, then it is downloaded on demand to
+@racket[(find-system-path 'addon-dir)].}
 
 Latex output with @racketmodname[scribble/jfp] uses a main-document
 version supplied to @racket[title] as the short-form document name (to
diff --git a/collects/scribblings/scribble/lncs.scrbl b/collects/scribblings/scribble/lncs.scrbl
index 222accc1..5bb45d38 100644
--- a/collects/scribblings/scribble/lncs.scrbl
+++ b/collects/scribblings/scribble/lncs.scrbl
@@ -14,13 +14,10 @@
   The @racketmodname[scribble/lncs]
 language is like @racketmodname[scribble/manual], but configured with
 Latex style defaults to use the @filepath{llncs.cls} class
-file.
-
-The class file must be downloaded from Springer and installed
-into the @racket[scribble/lncs] collection directory. (Run a module
-in the language @racketmodname[scribble/lncs] to learn the precise paths
-where the file may go.)
-}
+file. The class file is not included with Scribble due to license issues,
+but if the file is not manually installed into the
+@racket[scribble/lncs] collection, then it is downloaded on demand to
+@racket[(find-system-path 'addon-dir)].}
 
 @defproc[(abstract [pre-content pre-content?] ...) block?]{