Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Payara Server instance running on WSL with deploy-on-save breaks "Web Application" Ant projects #8144

Merged
merged 1 commit into from
Jan 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -468,12 +468,6 @@ private boolean notifyServer(J2eeModuleProvider provider, Iterable<Artifact> art
LOGGER.log(Level.FINEST, builder.toString());
}

try {
distributeOnSave(FileUtil.toFile(provider.getJ2eeModule().getContentDirectory()), artifacts);
} catch (IOException ex) {
LOGGER.log(Level.INFO, null, ex); // NOI18N
}

String instanceID = provider.getServerInstanceID ();
ServerInstance inst = ServerRegistry.getInstance ().getServerInstance (instanceID);
if (inst == null && "DEV-NULL".equals(instanceID)) { // NOI18N
Expand Down Expand Up @@ -603,161 +597,6 @@ private void runJPDAAppReloaded() {
}
}

private void distributeOnSave(File destDir, Iterable<Artifact> artifacts) throws IOException {

try {
FileObject destRoot = FileUtil.createFolder(destDir);

// create target FOs map keyed by relative paths
Enumeration<? extends FileObject> destFiles = destRoot.getChildren(true);
Map<String, FileObject> destMap = new HashMap<>();
int rootPathLen = destRoot.getPath().length();
for (; destFiles.hasMoreElements();) {
FileObject destFO = (FileObject) destFiles.nextElement();
destMap.put(destFO.getPath().substring(rootPathLen + 1), destFO);
}

FileObject contentDirectory = destRoot;
assert contentDirectory != null;

for (Artifact artifact : artifacts) {
File fsFile = artifact.getFile();
File altDistFile = artifact.getDistributionPath();
if (altDistFile == null) {
String classes = "target" + File.separator + "classes";
String filePath = artifact.getFile().getPath();
String altDistRelativePath = filePath.substring(filePath.indexOf(classes) + classes.length());
altDistFile = new File(destRoot.getPath() + File.separator + "WEB-INF" + File.separator + "classes" + altDistRelativePath);
}

FileObject file = FileUtil.toFileObject(FileUtil.normalizeFile(fsFile));

FileObject checkFile = FileUtil.toFileObject(FileUtil.normalizeFile(altDistFile));
if (checkFile == null && file != null) { //#165045
checkFile = FileUtil.createData(altDistFile);
}

if (checkFile != null && file != null) {
String relative = FileUtil.getRelativePath(contentDirectory, checkFile);
if (relative != null) {
FileObject targetFO = destMap.get(relative);
if (file.isFolder()) {
destMap.remove(relative);
//continue;
}

createOrReplace(file, targetFO, destRoot, relative, destMap, false);
}
} else if (checkFile != null && file == null) {
checkFile.delete();
}
}

} catch (Exception e) {
String msg = NbBundle.getMessage(DeployOnSaveManager.class, "MSG_IncrementalDeployFailed", e);
throw new RuntimeException(msg, e);
}
}

private void createOrReplace(
FileObject sourceFO,
FileObject targetFO,
FileObject destRoot,
String relativePath,
Map<String, FileObject> destMap, boolean checkTimeStamps) throws IOException {

FileObject destFolder;
OutputStream destStream = null;
InputStream sourceStream = null;

try {
// double check that the target does not exist... 107526
// the destMap seems to be incomplete....
if (targetFO == null) {
targetFO = destRoot.getFileObject(relativePath);
}
if (targetFO == null) {
destFolder = findOrCreateParentFolder(destRoot, relativePath);
} else {
// remove from map to form of to-remove-target-list
destMap.remove(relativePath);

//check timestamp
if (checkTimeStamps) {
if (!sourceFO.lastModified().after(targetFO.lastModified())) {
return;
}
}
if (targetFO.equals(sourceFO)) {
// do not write a file onto itself...
return;
}
destFolder = targetFO.getParent();

// we need to rewrite the content of the file here... thanks,
// to windows file locking.
destStream = targetFO.getOutputStream();

}

if (sourceFO.isFolder()) {
FileUtil.createFolder(destFolder, sourceFO.getNameExt());
return;
}
try {
if (null == destStream) {
FileUtil.copyFile(sourceFO, destFolder, sourceFO.getName());
} else {
// this is where we need to push the content into the file....
sourceStream = sourceFO.getInputStream();
FileUtil.copy(sourceStream, destStream);
}
} catch (FileNotFoundException ex) {
// this may happen when the source file disappears
// perhaps when source is changing rapidly ?
LOGGER.log(Level.INFO, null, ex);
}
} finally {
if (null != sourceStream) {
try {
sourceStream.close();
} catch (IOException ioe) {
LOGGER.log(Level.WARNING, null, ioe);
}
}
if (null != destStream) {
try {
destStream.close();
} catch (IOException ioe) {
LOGGER.log(Level.WARNING, null, ioe);
}
}
}
}

/**
* Find or create parent folder of a file given its root and its
* relative path. The target file does not need to exist.
*
* @param dest FileObject for the root of the target file
* @param relativePath relative path of the target file
* @return the FileObject for the parent folder target file.
* @throws java.io.IOException
*/
private FileObject findOrCreateParentFolder(FileObject dest, String relativePath) throws IOException {
File parentRelativePath = (new File(relativePath)).getParentFile();
if (parentRelativePath == null) {
return dest;
}

FileObject folder = FileUtil.createFolder(dest, parentRelativePath.getPath());
if (folder.isData()) {
LOGGER.log(Level.FINER, "found file {0} when a folder was expecetd", folder.getPath());
folder = null;
}
return folder;
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -1798,13 +1798,13 @@ meth protected void enableFields()
meth protected void initCheckBoxes()
meth protected void initCredentials()
meth protected void initDirectoriesFields()
meth protected void initDockerVolume()
meth protected void initInstanceType()
meth protected void initDomainAndTarget()
meth protected void initFlagsFromProperties(org.netbeans.modules.payara.common.ui.InstancePanel$CheckBoxProperties)
meth protected void initFormFields()
meth protected void storeCheckBoxes()
meth protected void storeCredentials()
meth protected void storeDockerVolume()
meth protected void storeInstanceType()
meth protected void storeFormFields()
meth protected void storeHost()
meth protected void storePorts()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1156,6 +1156,10 @@ && getInstance().getContainerPath() != null
&& !getInstance().getContainerPath().isEmpty()) {
Path relativePath = Paths.get(getInstance().getContainerPath()).relativize(Paths.get(path));
path = Paths.get(getInstance().getHostPath(), relativePath.toString()).toString();
} else if (getInstance().isWSL()) {
path = path.substring(5); // Remove the "/mnt/" part
path = path.substring(0, 1).toUpperCase() + ":" + path.substring(1); // Capitalize the first letter (drive letter)
path = path.replace("/", "\\");
} else {
path = (new File(path)).getAbsolutePath();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1031,25 +1031,51 @@ public String getAdminPassword() {
}

/**
* Get information if this Payara server instance is running in docker container.
* Get information if this Payara server instance is running in docker
* container.
* <p/>
* @return Value of <code>true</code> when this Payara server instance
* is docker instance or <code>false</code> otherwise.
* @return Value of <code>true</code> when this Payara server instance is
* docker instance or <code>false</code> otherwise.
*/
@Override
public boolean isDocker() {
return Boolean.valueOf(properties.getOrDefault(PayaraModule.DOCKER_ATTR, "false"));
return Boolean.parseBoolean(properties.getOrDefault(PayaraModule.DOCKER_ATTR, "false"));
}

/**
* Get information if this Payara server instance is running in wsl container.
* Sets the flag indicating if this Payara server instance is running in
* Docker container.
* <p/>
* @return Value of <code>true</code> when this Payara server instance
* is wsl instance or <code>false</code> otherwise.
* @param isDocker A boolean indicating if the instance is running in
* Docker.
*/
public void setDocker(boolean isDocker) {
properties.put(PayaraModule.DOCKER_ATTR, Boolean.toString(isDocker));
}

/**
* Get information if this Payara server instance is running in wsl
* container.
* <p/>
* @return Value of <code>true</code> when this Payara server instance is
* wsl instance or <code>false</code> otherwise.
*/
@Override
public boolean isWSL() {
return Boolean.valueOf(properties.getOrDefault(PayaraModule.WSL_ATTR, "false"));
return Boolean.parseBoolean(properties.getOrDefault(PayaraModule.WSL_ATTR, "false"));
}

/**
* Sets the flag indicating if this Payara server instance is running in
* Windows Subsystem for Linux (WSL).
* <p/>
* @param isWSL A boolean indicating if the instance is running in WSL.
*/
public void setWSL(boolean isWSL) {
properties.put(PayaraModule.WSL_ATTR, Boolean.toString(isWSL));
if (!isWSL) {
properties.put(PayaraModule.DOMAINS_FOLDER_ATTR, null);
}
}

/**
Expand Down Expand Up @@ -1097,7 +1123,13 @@ public void setContainerPath(final String containerPath) {
*/
@Override
public String getDomainsFolder() {
return properties.get(PayaraModule.DOMAINS_FOLDER_ATTR);
String domainsDir = properties.get(PayaraModule.DOMAINS_FOLDER_ATTR);
if(isDocker()) {
return null;
} else if(isWSL() && domainsDir == null) {
domainsDir = getPayaraRoot() + File.separator + "domains";
}
return domainsDir;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,6 @@ InstancePanel.userNameField.text=
InstancePanel.hostRemoteField.text=
InstancePanel.hotDeploy.text=Enable Hot Deploy
InstancePanel.showPassword.text=
InstancePanel.hostPathLabel.text=Host Path:
InstancePanel.hostPathField.text=
InstancePanel.containerPathLabel.text=Container Path:
InstancePanel.containerPathField.text=
ConnectionPoolAdvancedAttributesCustomizer.logJDBCCallsCheckbox.text=Enable
ConnectionPoolAdvancedAttributesCustomizer.logJDBCCallsLabel.text=Log JDBC Calls:
ConnectionPoolAdvancedAttributesCustomizer.logJDBCCallsLayeredPane.toolTipText=When set to true, all JDBC calls will be logged allowing tracing of all JDBC interactions including SQL
Expand All @@ -170,3 +166,12 @@ ConnectionPoolAdvancedAttributesCustomizer.slowQueryLogThresholdLayeredPane.tool
ConnectionPoolAdvancedAttributesCustomizer.sqlTraceListenersTextField.text=
ConnectionPoolAdvancedAttributesCustomizer.sqlTraceListenersLabel.text=SQL Trace Listeners:
ConnectionPoolAdvancedAttributesCustomizer.sqlTraceListenersLayeredPane.toolTipText=Comma-separated list of classes that implement the org.glassfish.api.jdbc.SQLTraceListener interface
InstancePanel.dockerInstance.text=Docker Volume
InstancePanel.wslInstance.text=WSL
InstancePanel.dockerInstance.toolTipText=Enable this option to connect with a Payara Server instance hosted in a Docker container.
InstancePanel.wslInstance.toolTipText=Enable WSL integration to connect with a Payara Server instance running inside Windows Subsystem for Linux. The host IP can be determined using the 'hostname -I' command in WSL.
InstancePanel.hostPathField.text=
InstancePanel.containerPathField.text=
InstancePanel.hostPathLabel.text=Host Path:
InstancePanel.containerPathLabel.text=Container Path:
InstancePanel.instanceTypeLabel.text=Instance Type:
Loading
Loading