Bug 58086 - Deploy WAR file using http:// throws FileNotFoundException
Summary: Deploy WAR file using http:// throws FileNotFoundException
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 7
Classification: Unclassified
Component: Manager (show other bugs)
Version: unspecified
Hardware: All All
: P2 normal (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-06-30 20:48 UTC by Lukasz Jader
Modified: 2015-07-08 12:02 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Lukasz Jader 2015-06-30 20:48:45 UTC
Hi all.
I have an Ant target which deploys WAR file to Tomcat7 instance using taskdef for DeployTask class.
WAR file is passed as URL - http://
I'm executing this on Windows 7 64bit with JDK 1.7

Sample part of failing target:
<tomcat-deploy url="http://localhost:8080/manager/text" path="/testdeploy" war="http://server.pl/app.war"
			username="user" password="pass"
			failOnError="true" logerror="true"/>

This execution fails and exception is thrown (sorry for Polish message):

test_deploy.xml:37: java.io.FileNotFoundException: http:\server.pl\app.war (Nazwa pliku, nazwa katalogu lub skladnia etykiety woluminu jest niepoprawna)
        at java.io.FileInputStream.open(Native Method)
        at java.io.FileInputStream.<init>(FileInputStream.java:146)
        at java.io.FileInputStream.<init>(FileInputStream.java:101)
        at org.apache.catalina.ant.DeployTask.execute(DeployTask.java:155)
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.Task.perform(Task.java:348)
        at org.apache.tools.ant.Target.execute(Target.java:435)
        at org.apache.tools.ant.Target.performTasks(Target.java:456)
        at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393)
        at org.apache.tools.ant.Project.executeTarget(Project.java:1364)
        at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
        at org.apache.tools.ant.Project.executeTargets(Project.java:1248)
        at org.apache.tools.ant.Main.runBuild(Main.java:851)
        at org.apache.tools.ant.Main.startAnt(Main.java:235)
        at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
        at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)

== Question ==
Does implementation of DeployTask is incorrect?

I think there is error in content of this "if" - I think it should be replaced with "else" code:
https://github.com/apache/tomcat/blob/trunk/java/org/apache/catalina/ant/DeployTask.java#L143

Or I am using this task the wrong way?
Comment 1 Violeta Georgieva 2015-07-01 07:25:21 UTC
Hi,

Fix was made available in trunk, in 8.0.x for 8.0.24 and in 7.0.x for 7.0.64 onwards.

Regards,
Violeta
Comment 2 Lukasz Jader 2015-07-06 17:38:24 UTC
@Violeta Georgieva

I'm searching a little bit more about this and I found out, 
that this is much more complicated issue - sorry for misleading you.

Previous implementation worked for all kind of local filesystem files, because when:
a) war="C:/Users/john/app.war"
  was loaded using FileInputStream
b) war="file:/C:/Users/john/app.war"
  was loaded using URL and URLConnection (effectively FileURLConnection)

But it does not worked other protocols (ex. "http", "https"), 
since it tried to load them using "FileInputStream".


Current implementation (AFTER FIX) does NOT WORK for any of local filesystem files, because when:
a) war="C:/Users/john/app.war"
  was loaded using URL and URLConnection - and the exception is thrown java.net.MalformedURLException: no protocol
b) war="file:/C:/Users/john/app.war"
  was is loaded using FileInputStream, which in constructor uses java.io.File, 
  which incorrectly handles files URIs in different situations:
    https://weblogs.java.net/blog/kohsuke/archive/2007/04/how_to_convert.html
    http://bugs.java.com/view_bug.do?bug_id=5086147
	https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/FileUtils.html#toFile%28java.net.URL%29


I don't see any quick solution to this fix :(.
I think the best way would be reverting previous commit and figuring out
how to implement this.

For my own needs I've dirty fixed this problem to:
if (war.startsWith("file:") || war.startsWith("http:") || war.startsWith("https:")) {
  //execute the URL code
} else {
  //execute the File code as fallback
}
Comment 3 Violeta Georgieva 2015-07-08 12:02:57 UTC
Hi,

Thanks for the testing.

The new fix was made available in trunk, in 8.0.x for 8.0.25 and in 7.0.x for 7.0.64 onwards.

Regards,
Violeta