I am currently migrating an app from Websphere 9 to Liberty. I have an issue which I don't know if it is a bug from Liberty or a configuration issue from my side. Server.xml:
<?xml version="1.0" encoding="UTF-8"?>
<server description="new server">
<!-- Enable features -->
<featureManager>
<feature>javaee-7.0</feature>
<feature>jaxws-2.2</feature>
<feature>appSecurity-2.0</feature>
<feature>beanValidation-1.1</feature>
<feature>cdi-1.2</feature>
<feature>ejbLite-3.2</feature>
<feature>el-3.0</feature>
<feature>javaMail-1.5</feature>
<feature>jdbc-4.1</feature>
<feature>jndi-1.0</feature>
<feature>jpa-2.1</feature>
<feature>jsp-2.3</feature>
<feature>jaspic-1.1</feature>
<feature>localConnector-1.0</feature>
<feature>servlet-3.1</feature>
<feature>ejbRemote-3.2</feature>
<feature>heritageAPIs-1.1</feature>
</featureManager>
<logging messageFormat="console" messageSource="message,trace,accessLog,ffdc,audit" />
<library id="sharedlib">
<fileset dir="/liberty/usr/shared/lib/global" includes="*.jar" scanInterval="5s" />
</library>
<dataSource id="DefaultDataSource" jndiName="jdbc/postgres/PreferencesDb">
<jdbcDriver libraryRef="PostgresLib"/>
<properties.postgresql databaseName="dbname" user="dbuser" password="dbpassword" serverName="host.docker.internal" portNumber="5433"/>
</dataSource>
<library id="PostgresLib">
<file name="/liberty/usr/shared/lib/postgresql-42.7.1.jar"/>
</library>
<jspEngine keepGenerated ="true"/>
<basicRegistry id="basic" realm="BasicRealm">
<user name="wsadmin" password="wsadmin" />>
</basicRegistry>
<!-- To allow access to this server from a remote client host="*" has been added to the following element -->
<httpEndpoint id="defaultHttpEndpoint"
host="*"
httpPort="9080"
httpsPort="9445" />
<iiopEndpoint id="defaultIiopEndpoint" iiopPort="2910">
<iiopsOptions iiopsPort="9503" sslRef="defaultSSLConfig"/>
</iiopEndpoint>
<!-- Automatically expand WAR files and EAR files -->
<applicationManager autoExpand="true"/>
<application type="ear" id="AServer" location="Aserver.ear" name="a-server" startAfterRef="a-bootstrap" >
<classloader commonLibraryRef="sharedlib"/>
</application>
<application type="ear" id="a-bootstrap" location="/liberty/usr/shared/apps/a-bootstrap.ear" name="a-bootstrap">
<classloader commonLibraryRef="sharedlib" />
</application>
</server>
When I deploy my app (ear) and load a page handled by a JSP, I have a FileNotFoundException:
java.io.FileNotFoundException: /opt/ibm/wlp/output/[redacted]/workarea/org.eclipse.osgi/73/data/temp/default_node/SMF_WebContainer/[redacted]/[redacted]/jsp/_index.java (No such file or directory)
at java.io.FileOutputStream.open(FileOutputStream.java:313)
at java.io.FileOutputStream.<init>(FileOutputStream.java:253)
at java.io.FileOutputStream.<init>(FileOutputStream.java:139)
at com.ibm.ws.jsp.translator.visitor.generator.JavaFileWriter.<init>(JavaFileWriter.java:43)
at com.ibm.ws.jsp.translator.visitor.generator.GenerateVisitor.createWriter(GenerateVisitor.java:72)
at com.ibm.ws.jsp.translator.visitor.generator.GenerateJspVisitor.<init>(GenerateJspVisitor.java:59)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
The issue seems to be that "/jsp" (or any other subfolders) are not existing when new FileOutputStream() is instantiated. If I create manually the folders, it is working.
If I launch liberty in debug mode, the folders get created and the JSP are properly generated ! And if after that, I launch the server without debug, it is also working.
Thus, I analyzed the differences between debug mode and regular mode, why the debug mode is creating the folders.
It is working in debug because of this OpenLibery class: AbstractJSPExtensionServletWrapper.java:331 :
if (translationRequired == false && options.isDebugEnabled()) {
translationRequired = (this.debugClassFile == false);
// defect 182990 begin
// in WDT, we need to re-translate the JSP on each server startup so the debugger can be invoked on a JSP file
if (!translationRequired && getTarget() == null){
translationRequired = true;
}
//defect 182990 end
// defect 272935 begin
if (translationRequired && jspResources.getGeneratedSourceFile().getParentFile().exists() == false){
boolean rc = jspResources.getGeneratedSourceFile().getParentFile().mkdirs();
if(com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable(Level.FINEST)){
logger.logp(Level.FINEST, CLASS_NAME, "_checkForTranslation", (rc?"Created":"Unable to create") +" directory for generated source file ["+jspResources.getGeneratedSourceFile().getParentFile() +"]");
}
}
// defect 272935 end
}
This code is executed only in debug mode and will mkdirs() the missing folder.
My question is, why is it for debug only, and what am I missing for the regular mode to generate those folders as well ?
Thanks