This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 181444 - Compile on save support on maven war project with Tomcat
Summary: Compile on save support on maven war project with Tomcat
Status: RESOLVED FIXED
Alias: None
Product: javaee
Classification: Unclassified
Component: Maven (show other bugs)
Version: 6.x
Hardware: All All
: P2 normal with 5 votes (vote)
Assignee: Petr Hejl
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-03-02 12:04 UTC by cbosquet
Modified: 2010-11-24 22:00 UTC (History)
5 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
Sample application to reproduce the issue (4.83 KB, application/zip)
2010-03-02 12:04 UTC, cbosquet
Details
patch (1.13 KB, patch)
2010-11-11 00:05 UTC, David Konecny
Details | Diff
patch (2.50 KB, patch)
2010-11-17 01:37 UTC, David Konecny
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description cbosquet 2010-03-02 12:04:14 UTC
Created attachment 94700 [details]
Sample application to reproduce the issue

I work on Java Web projects using :
 - netbeans 6.8 (or 6.7.1, 6.9 m1)
 - maven 2.2.1 (or 2.0.9, ...)
 - Tomcat 6.0 (or 5.5, ...)
Actually, when i activate "compile on save" feature on web projects, Netbeans copy classes in "target/classes" folder. But Tomcat use "target/${artifactId}/WEB-INF/classes" folder to load classes.
I think that classes should be also copied in "target/${artifactId}/WEB-INF/classes" in this case (and may be in others cases...).
I have attached a very simple sample project to show the case.

NB. I deploy my application on Tomcat using Run or Debug menu.

Best regards,
Charles Bosquet
Comment 1 Milos Kleint 2010-03-02 12:15:05 UTC
phejl: does deploy on save support include tomcat?
Comment 2 Petr Hejl 2010-03-02 12:33:00 UTC
Yep. Unless there is a bug it should work.
In fact the only supported servers are Tomcat and GlassFish so far.
Comment 3 tprochazka 2010-04-23 08:58:13 UTC
If compiled class will be copied also to target/${artifactId}/WEB-INF/classes folder will be possible use also Java Rebel for hot swap (why this doesn't do Java myself :-(). For now it's possible make symbolic link for target/${artifactId}/WEB-INF/classes to classes folder, but this will be removed for every clear of project :-(

Will be this fixed for NB 6.9?
Comment 4 Antonin Nebuzelsky 2010-07-30 15:18:27 UTC
Reassigning to default owner.
Comment 5 mandrews 2010-11-04 14:35:25 UTC
Glad to see this is getting discussed. This is pretty important for us web developers (and one of the issues I'm having in moving my dev team off the E word).

- The Tomcat context that is written on deployment should have the "reloadable" attribute set to "true"
- recompiled classes should be additionally written to WEB-INF/classes dir.

That should do it.  Hopefully this can get into an upcoming release.

Thanks,
Michael
Comment 6 David Konecny 2010-11-10 23:59:33 UTC
(In reply to comment #5)
> - The Tomcat context that is written on deployment should have the "reloadable"
> attribute set to "true"

Could you create a new issue for this request please? Use issuezilla component: serverplugins/tomcat. Thx.
Comment 7 David Konecny 2010-11-11 00:05:12 UTC
Created attachment 102896 [details]
patch

Petr Hejl, attached is patch for j2eeserver module which fixes the problem. Initially I thought the problem is in Maven EE support but ended up debugging ServerFileDistributor which has two versions of _distributeOnSave. Eliminating one which does not handle artifact.getDistributionPath correctly resolved the issue. Could you verify it is a right fix please?

Btw. this is server independent issue - GF should be impacted the same way as Tomcat.
Comment 8 Petr Hejl 2010-11-11 10:18:07 UTC
The ServerFileDistributor is really fragile. I'm bit afraid of what this change may cause.

The _distributeOnSave(module, artifacts) is called when destDir is null which should mean the files are already in place (copying done by the build itself for example). So your fix could imo do unnecessary file copies in cases when it is not really needed. Do you know why the destDir is null?


Can you provide simple test scenario or test case? I'd like to debug the issue as well.
Comment 9 David Konecny 2010-11-11 19:55:47 UTC
(In reply to comment #8)
> Can you provide simple test scenario or test case? I'd like to debug the issue
> as well.

There is some attached to this issue but what's need is: create Maven Web project and create Servlet class in it; now when you Save the servlet you will see that it was compiled and copied to target/classes but not to target/<your-project-name>/WEB-INF/classes.
Comment 10 Petr Hejl 2010-11-16 11:08:48 UTC
(In reply to comment #9)
> (In reply to comment #8)
> > Can you provide simple test scenario or test case? I'd like to debug the issue
> > as well.
> 
> There is some attached to this issue but what's need is: create Maven Web
> project and create Servlet class in it; now when you Save the servlet you will
> see that it was compiled and copied to target/classes but not to
> target/<your-project-name>/WEB-INF/classes.

This works OK for GF so it is Tomcat specific issue.
Comment 11 David Konecny 2010-11-16 22:53:52 UTC
More info:

(In reply to comment #8)
> The _distributeOnSave(module, artifacts) is called when destDir is null which
> should mean the files are already in place (copying done by the build itself
> for example).

destDir is null because TomcatIncrementalDeployment.getDirectoryForModule is not implemented and returns null. In Ant projects this is not a problem because CoS automatically compiles java files directly to build/web/WEB-INF/classes. But in Maven projects CoS compiles java files to target/classes and from there *somebody* has to copy them to target/${artifactId}/WEB-INF/classes. And that somebody is currently "deployment support" (j2eeserver module).

There is second problem. Deployment support in order to do its job properly depends on project having a server (which is optional in Maven projects) and on server running and on module being deployed. Only when these three conditions are met it works properly.

Here is test case which fails on GlassFish:
#1) create Maven Web Project; enable CoS; create a Servlet; run the project; select GlassFish server permanently
#2) create a SecondServlet in IDE and verify that SecondServlet.class was created in target/<your-maven-proj>/WEB-INF/classes; so far everything works fine
#3) restart IDE
#4) create ThirdServlet -> because GlassFish is not running ThirdServlet.class is not create in target/<your-maven-proj>/WEB-INF/classes

PetrH, could you have a look at first problem in Tomcat server plugin. I'm going to look at the second problem.
Comment 12 David Konecny 2010-11-17 01:37:45 UTC
Created attachment 103024 [details]
patch

Here is another patch idea I would like to ask for your opinion PetrH. Basically when CoS reports an event that a class was autocompiled then that class should be copied to WEB-INF/classes folder. There is no need (as far as I can see) why that operation should depend on server. I would implement it completely separately of j2eeserver module but DeployOnSaveManager does everything what's needed so for now I just placed it there.

This patches solved both of the problems I talked about in my previous post. To be honest I do not understand why it was not done this way since the beginning and what is exact role of ServerFileDistributor in all this. I understand aspect of ServerFileDistributor which enumerates all changed files and then tells server to reload these. That make sense.
Comment 13 David Konecny 2010-11-17 03:15:55 UTC
I would like to add that when I said

(In reply to comment #12)
> This patches solved both of the problems I talked about in my previous post. To
> be honest I do not understand why it was not done this way since the beginning
> and what is exact role of ServerFileDistributor in all this.

I was referring to Web Project (and that should be applicable also to EJB Project). For EAR project situation is different: it is server plugin which creates expanded EAR directory structure ready for deployment. Looking at the problems defined in comment #11 problem #1 is not relevant as you cannot deploy EAR to Tomcat and there is no solution for problem #2 apart from keeping app deployed to server and server running. Did I got it right or ... ?

Btw. be aware: the patch I attached is not very defensive and throws exceptions
Comment 14 David Konecny 2010-11-23 00:40:46 UTC
ab85318f76a5

I'm committing Petr's latest patch which he sent me offline and which fixes the problem.
Comment 15 David Konecny 2010-11-24 22:00:02 UTC
This should be available in nightly builds later this week (Fri/Sat). I would appreciate if somebody could verify it works as expected. Thanks.