v6/v7 lar archive mapping - Invalid OSGi bundle error

OS: Windows 11
Java Version: amazon-corretto-21.0.10.7.1
Tomcat Version: 11
Lucee Version: Lucee Express 6.2.5.48 and 7.0.2.106

Hello! I’m trying to upgrade an app from Lucee Express 5.3.8.189 to either Lucee Express 6.2.5.48 or 7.0.2.106. I have several mappings and .lar archives without including the CFML source and removing the mapped file from the physical path. This works fine in v5 just running the app from the java byte code in the lar. In v6 and v7, I’ve run into various roadblocks. The primary issue is that in v6/v7, it’s throwing error “Invalid OSGi bundle structure…not a valid bundle”. Since the lar is not passing the OSGi bundle validation, it’s unable to use the lar.

Separately, in the admin interface, setting the primary drop down to “archive” never takes in either the config.json or the mapping table after saving the mapping. In v7, it tries to create the lar inside of the lucee-context.lar and gives a wonky path starting with “zip” rather than making a new archives folder with the lar like v5/v6 did. I can get around the interface errors, but not the OSGi bundle validation error. If there is a way around the OSGi bundle validation errors, i would very much appreciate any guidance. thank you

Can you share steps to reproduce and any stacktraces?

@Zackster , The Steps I followed to recreat “Invalid OSGi bundle” Error in Lucee 6/7:
Created a Lucee 5.3.8.189 application folder.
Packaged the folder into a LAR via Lucee Admin.
Opened the LAR and deleted all CFML source files.
Added the LAR as an archive/mapping in the Lucee Admin 6.2.5.48 / 7.0.2.106.
Observed the OSGi validation error: …is not a valid bundle!

This issue appeared in log file.

"ERROR","http-nio-8888-exec-2","03/18/2026","13:38:20","OSGi","C:\portables\lucee-express-5.3.8.189\webapps\ROOT\WEB-INF\lucee\context\archives\archive-sample1.lar is not a valid bundle!;org.osgi.framework.BundleException: C:\portables\lucee-express-5.3.8.189\webapps\ROOT\WEB-INF\lucee\context\archives\archive-sample1.lar is not a valid bundle!
	at lucee.runtime.osgi.OSGiUtil.installBundle(OSGiUtil.java:180)
	at lucee.runtime.MappingImpl.initArchive(MappingImpl.java:204)
	at lucee.runtime.MappingImpl.getArchive(MappingImpl.java:377)
	at lucee.runtime.MappingImpl.check(MappingImpl.java:537)
	at lucee.runtime.config.ConfigImpl.initMappings(ConfigImpl.java:859)
	at lucee.runtime.config.ConfigImpl.setMappings(ConfigImpl.java:820)
	at lucee.runtime.config.ConfigWebFactory._loadMappings(ConfigWebFactory.java:2038)
	at lucee.runtime.config.ConfigWebFactory.load(ConfigWebFactory.java:631)
	at lucee.runtime.config.ConfigServerFactory.load(ConfigServerFactory.java:267)
	at lucee.runtime.config.ConfigServerFactory.reloadInstance(ConfigServerFactory.java:239)
	at lucee.runtime.config.ConfigAdmin._reload(ConfigAdmin.java:377)
	at lucee.runtime.config.ConfigAdmin._reload(ConfigAdmin.java:368)
	at lucee.runtime.config.ConfigAdmin.storeAndReload(ConfigAdmin.java:330)
	at lucee.runtime.tag.Admin.store(Admin.java:5273)
	at lucee.runtime.tag.Admin.doUpdateMapping(Admin.java:2100)
	at lucee.runtime.tag.Admin._doStartTag(Admin.java:741)
	at lucee.runtime.tag.Admin.doStartTag(Admin.java:361)
	at resources_mappings_cfm460$cf.call(/admin/resources.mappings.cfm:141)
	at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1118)
	at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1012)
	at lucee.runtime.PageContextImpl.doInclude(PageContextImpl.java:993)
	at web_cfm$cf.call_000007(/admin/web.cfm:521)
	at web_cfm$cf.call(/admin/web.cfm:515)
	at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1118)
	at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1012)
	at lucee.runtime.PageContextImpl.doInclude(PageContextImpl.java:993)
	at server_cfm$cf.call(/admin/server.cfm:7)
	at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1118)
	at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1012)
	at lucee.runtime.listener.ModernAppListener._onRequest(ModernAppListener.java:215)
	at lucee.runtime.listener.MixedAppListener.onRequest(MixedAppListener.java:43)
	at lucee.runtime.PageContextImpl.execute(PageContextImpl.java:2816)
	at lucee.runtime.PageContextImpl._execute(PageContextImpl.java:2803)
	at lucee.runtime.PageContextImpl.executeCFML(PageContextImpl.java:2774)
	at lucee.runtime.engine.Request.exe(Request.java:45)
	at lucee.runtime.engine.CFMLEngineImpl._service(CFMLEngineImpl.java:1113)
	at lucee.runtime.engine.CFMLEngineImpl.serviceCFML(CFMLEngineImpl.java:1070)
	at lucee.loader.engine.CFMLEngineWrapper.serviceCFML(CFMLEngineWrapper.java:97)
	at lucee.loader.servlet.CFMLServlet.service(CFMLServlet.java:51)
..."

@shavj , I just want to confirm if this matches the exact issue you encountered.

Try regenerating the .lar with the Lucee version in use?

bytecode compatibility between major releases may break.

While we try to avoid it, it’s only source code which will be compatible unless noted otherwise (i.e listed as a breaking change)

thanks for your help on this. i should have mentioned in the original post that the lars were created by lucee in each specific version. i knew that lars from v5 were likely not compatible with v6/v7, so i recreated the lars in each version. the exact steps:

  1. put test.cfm source code file in physical path: C:/lucee6/webapps/ROOT/deploy/
  2. create new mapping with virtual=/h, resource=C:/lucee6/webapps/ROOT/deploy/, archive={blank}, resource=archive, inspect=once
  3. edit the new mapping
  4. uncheck both “Add all CFML Source…” and “Add all Non CFML Source…”
  5. click “assign archive to mapping button”
  6. remove test.cfm source code from C:/lucee6/webapps/ROOT/deploy/
  7. go to http://localhost:8888/h/test.cfm in browser

in lucee 5, this worked and processed the java byte code in the lar. in lucee 6/7 the application.log shows the below errors. since 6/7 are treating the lar as an OSGi bundle and trying to validate it as such, it errors out, and marks the archive path as invalid. the browser falls back to the physical path and cannot find the file because i removed the source code from the physical path. i was doing this as a light protection of source code, which is why i dont want to bundle the source code in the lar or keep the file in the physical path

following the above steps in lucee 7 express, it tries to bundle my lar with \lucee-server\context\context\lucee-context.lar\ (instead of create an archives folder and new lar) and it creates a wonky archive path starting with “zip” and all the images and css disappear from the admin interface.

"Severity","ThreadID","Date","Time","Application","Message"
"ERROR","http-nio-8888-exec-4","03/17/2026","19:46:35","bundle","Invalid OSGi bundle structure in [archive-h.lar]: This bundle contains only Java class files but does not declare any 'Export-Package' entries in its manifest. According to OSGi specifications, bundles that contain classes intended for use by other bundles must explicitly export their packages. Please add appropriate 'Export-Package' declarations to the MANIFEST.MF file.;java.io.IOException: Invalid OSGi bundle structure in [archive-h.lar]: This bundle contains only Java class files but does not declare any 'Export-Package' entries in its manifest. According to OSGi specifications, bundles that contain classes intended for use by other bundles must explicitly export their packages. Please add appropriate 'Export-Package' declarations to the MANIFEST.MF file.

"ERROR","http-nio-8888-exec-4","03/17/2026","19:46:35","OSGi","C:\lucee6\lucee-server\context\context\archives\archive-h.lar is not a valid bundle!;org.osgi.framework.BundleException: C:\lucee6\lucee-server\context\context\archives\archive-h.lar is not a valid bundle!

Thanks for the additional detail, I’m investigating

https://luceeserver.atlassian.net/browse/LDEV-6165

Fixed in 6.2.6.5-SNAPSHOT and 7.0.3.19-SNAPSHOT

Also updated the docs

thanks @shavj !

awesome!! thank you @Zackster !

@Zackster i tried this out in Lucee Express 7.0.3.19-SNAPSHOT and it works when bypassing the interface and using cfscript admin “updateMapping” and “createArchive”, but using the same settings in the interface still gives the wonky zip path. with cfscript, if you leave the archive key blank, “createArchive” doesnt end up populating the archive path. you either need to set the archive path in the cfscript “updateMapping”, or, after running the cfscript with the blank archive path, you need to go back into the admin interface and manually populate the archive path in the form field

if you try to create the mapping and archive in the admin interface, these are the results:

it is still doing this as the archive path: zip://C:\lucee70319\lucee-server\context\context\lucee-context.lar!/archives/archive-q.lar

browsing to http://localhost:8888/q/test.cfm, shows: Page [/q/test.cfm] [C:\lucee70319\webapps\ROOT\deploy\test.cfm] not found (ie archive path is getting marked as invalid so it’s falling back to physical path, which does not exist since i removed the file from the physical path)

Application.log has: http://localhost:8888",“OSGi”,"only file resources (local file system) are supportedjava.io.IOException: only file resources (local file system) are supported

full stack from Application.log:

"Severity","ThreadID","Date","Time","Context","Application","Message"
"ERROR","http-nio-8888-exec-7","03/19/2026","10:22:53","http://localhost:8888","OSGi","only file resources (local file system) are supportedjava.io.IOException: only file resources (local file system) are supported
	at lucee.runtime.osgi.BundleInfo.toFileResource(BundleInfo.java:406)
	at lucee.runtime.osgi.BundleFile.getInstance(BundleFile.java:57)
	at lucee.runtime.osgi.OSGiUtil.installBundle(OSGiUtil.java:194)
	at lucee.runtime.MappingImpl.initArchive(MappingImpl.java:201)
	at lucee.runtime.MappingImpl.getArchive(MappingImpl.java:359)
	at lucee.runtime.MappingImpl.check(MappingImpl.java:519)
	at lucee.runtime.config.ConfigImpl.initMappings(ConfigImpl.java:1597)
	at lucee.runtime.config.ConfigImpl.getMappings(ConfigImpl.java:1486)
	at lucee.runtime.config.ConfigWebImpl.getMappings(ConfigWebImpl.java:1746)
	at lucee.runtime.config.ConfigUtil.getSources(ConfigUtil.java:1233)
	at lucee.runtime.config.ConfigUtil.getPageSources(ConfigUtil.java:1107)
	at lucee.runtime.config.ConfigWebImpl.getPageSources(ConfigWebImpl.java:407)
	at lucee.runtime.PageContextImpl.getPageSource(PageContextImpl.java:965)
	at lucee.runtime.functions.system.CallStackGet.abs(CallStackGet.java:175)
	at lucee.runtime.functions.system.CallStackGet._getTagContext(CallStackGet.java:163)
	at lucee.runtime.functions.system.CallStackGet.call(CallStackGet.java:57)
	at lucee.runtime.functions.system.CallStackGet.call(CallStackGet.java:70)
	at lucee.runtime.functions.system.CallStackGet.call(CallStackGet.java:62)
	at lucee.runtime.tag.Location.doStartTag(Location.java:159)
	at resources_mappings_cfm460$cf.call(/admin/resources.mappings.cfm:182)
	at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1125)
	at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1019)
	at lucee.runtime.PageContextImpl.doInclude(PageContextImpl.java:1000)
	at web_cfm$cf.call_000013(/admin/web.cfm:528)
	at web_cfm$cf.call(/admin/web.cfm:522)
	at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1125)
	at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1019)
	at lucee.runtime.PageContextImpl.doInclude(PageContextImpl.java:1000)
	at index_cfm$cf.call(/admin/index.cfm:3)
	at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1125)
	at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1019)
	at lucee.runtime.listener.ModernAppListener._onRequest(ModernAppListener.java:239)
	at lucee.runtime.listener.ModernAppListener.onRequest(ModernAppListener.java:108)
	at lucee.runtime.PageContextImpl.execute(PageContextImpl.java:2817)
	at lucee.runtime.PageContextImpl._execute(PageContextImpl.java:2804)
	at lucee.runtime.PageContextImpl.executeCFML(PageContextImpl.java:2775)
	at lucee.runtime.engine.Request.exe(Request.java:45)
	at lucee.runtime.engine.CFMLEngineImpl._service(CFMLEngineImpl.java:1208)
	at lucee.runtime.engine.CFMLEngineImpl.serviceCFML(CFMLEngineImpl.java:1165)
	at lucee.loader.engine.CFMLEngineWrapper.serviceCFML(CFMLEngineWrapper.java:99)
	at lucee.loader.servlet.jakarta.CFMLServlet.service(CFMLServlet.java:41)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:710)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:128)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:107)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:165)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:77)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:492)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:113)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:83)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:654)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:72)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1779)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:946)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:480)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:57)
	at java.base/java.lang.Thread.run(Unknown Source)
"
"ERROR","ControllerThread:49","03/19/2026","10:23:18","http://localhost:8888","OSGi","only file resources (local file system) are supportedjava.io.IOException: only file resources (local file system) are supported
	at lucee.runtime.osgi.BundleInfo.toFileResource(BundleInfo.java:406)
	at lucee.runtime.osgi.BundleFile.getInstance(BundleFile.java:57)
	at lucee.runtime.osgi.OSGiUtil.installBundle(OSGiUtil.java:194)
	at lucee.runtime.MappingImpl.initArchive(MappingImpl.java:201)
	at lucee.runtime.MappingImpl.getArchive(MappingImpl.java:359)
	at lucee.runtime.MappingImpl.check(MappingImpl.java:519)
	at lucee.runtime.config.ConfigImpl.initMappings(ConfigImpl.java:1597)
	at lucee.runtime.config.ConfigImpl.checkMappings(ConfigImpl.java:1587)
	at lucee.runtime.config.ConfigWebImpl.checkMappings(ConfigWebImpl.java:1995)
	at lucee.runtime.engine.Controler.doCheckMappings(Controler.java:654)
	at lucee.runtime.engine.Controler.control(Controler.java:446)
	at lucee.runtime.engine.Controler.control(Controler.java:283)
	at lucee.runtime.engine.Controler$ControlerThread.run(Controler.java:129)
"

bug filed

https://luceeserver.atlassian.net/browse/LDEV-6176

ended up with a whole epic related to archives bugs (not used very often)

https://luceeserver.atlassian.net/browse/LDEV-6175

thank you!

check the latest 7.0.3 snapshot?

1 Like

@Zackster looks great! in 7.0.3.25-SNAPSHOT, everything is now working as expected in the interface. steps tested: create the mapping with blank archive field, put .cfm source file in the physical path, edit the mapping, uncheck both “Add all CFML Source” and “Add all Non CFML Source”, click “assign archive to mapping”, remove source file from physical path. check mapping/file path in browser. results: archive path successfully created in both interface and config.json, lar successfully created at path \lucee-server\context\context\archives, browser successfully finds lar archive via the archive mapping and displays page. thanks so much for resolving!

1 Like