avisi-cloud/structurizr-site-generatr

Serve watch throws `java.io.FileNotFoundException` on update (windows)

chipbite opened this issue · 4 comments

Hi!

Serve watch throws java.io.FileNotFoundException when file change is detected

I start generatr to run locally and it watches for any changes.

It is triggered correctly when a files is updated. But it almost (like 95% of the time) always consistently throws a filenotfoundexception when it tries to act on the change and reload the site.

See output below.

It seems to be a similar file handling issue, to the issue that we saw during startup (now fixed).

Hoping it is an easy fix!

Workaround: Kill and restart generatr server.

Let me know if there is anything other output that I can supply.

Output:

Detected a change in C:\code\c4-demo-stuff\ipex-architecture\c4-dsl\dexf, updating site...
juni 26, 2024 12:14:46 EM com.structurizr.dsl.StructurizrDslParser parse
WARNING: !constant has been deprecated and will be removed in a future release - please use !const or !var instead
Generating index page...
Copying assets...
Writing workspace.json...
Generating diagrams...
Kompis-Account UP-TO-DATE
space_containerview UP-TO-DATE
ipex-landscape1 UP-TO-DATE
space_Context UP-TO-DATE
space_componentview UP-TO-DATE
Kompis-Save UP-TO-DATE
kvadrat_componentview UP-TO-DATE
corelib_componentview UP-TO-DATE
kvadrat_containerview UP-TO-DATE
Context-DEXF-Account UP-TO-DATE
flow-kompis-auth UP-TO-DATE
kvadrat_Context UP-TO-DATE
Kompis-Context UP-TO-DATE
Generating site...
java.io.FileNotFoundException
        at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
        at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:542)
        at java.base/java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:567)
        at java.base/java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:670)
        at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:160)
        at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(ForEachOps.java:174)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
        at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
        at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:765)
        at nl.avisi.structurizr.site.generatr.site.SiteGeneratorKt.generateHtmlFiles(SiteGenerator.kt:202)
        at nl.avisi.structurizr.site.generatr.site.SiteGeneratorKt.generateSite(SiteGenerator.kt:87)
        at nl.avisi.structurizr.site.generatr.ServeCommand.updateSite(ServeCommand.kt:83)
        at nl.avisi.structurizr.site.generatr.ServeCommand.monitorFileChanges(ServeCommand.kt:175)
        at nl.avisi.structurizr.site.generatr.ServeCommand.startWatchService$lambda$12(ServeCommand.kt:147)
        at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.io.FileNotFoundException: build\serve\master\index.html (The requested operation cannot be performed on a file with a user-mapped section open)
        at java.base/java.io.FileOutputStream.open0(Native Method)
        at java.base/java.io.FileOutputStream.open(FileOutputStream.java:289)
        at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:230)
        at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:179)
        at kotlin.io.FilesKt__FileReadWriteKt.writeText(FileReadWrite.kt:141)
        at kotlin.io.FilesKt__FileReadWriteKt.writeText$default(FileReadWrite.kt:140)
        at nl.avisi.structurizr.site.generatr.site.SiteGeneratorKt.writeHtmlFile(SiteGenerator.kt:239)
        at nl.avisi.structurizr.site.generatr.site.SiteGeneratorKt.generateHtmlFiles$lambda$52$lambda$11(SiteGenerator.kt:130)
        at nl.avisi.structurizr.site.generatr.site.SiteGeneratorKt.generateHtmlFiles$lambda$53(SiteGenerator.kt:202)
        at nl.avisi.structurizr.site.generatr.site.SiteGeneratorKt.generateHtmlFiles$lambda$54(SiteGenerator.kt:202)
        at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
        at java.base/java.util.AbstractList$RandomAccessSpliterator.forEachRemaining(AbstractList.java:722)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
        at java.base/java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291)
        at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:754)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)

Looks like something (the embedded web server?) is keeping files open and that blocks the generator to overwrite the html file(s). Unfortunately I don't have a windows box close to me for further investigation, so any help is appreciated.