Reload Class When Dependent Resource Changes in Spring - java

You know how Eclipse reloads classes automatically running in Tomcat when resource files they depend on such as spring context files are updated so that you don't have to re-start Tomcat? How do I make a class dependent on a resource file so that Eclipse re-publishes it when the resource file changes? Eclipse would re-publish Spring classes when their dependent resource files are updated, but would not re-publish mine.

I'm not sure if it's Spring that's doing this for you. Are you developing in an IDE like Eclipse or Netbeans? What might be happening is as you make code changes your IDE is 'publishing' (i.e. re-deploying) your app code, so the app re-initializes every time the IDE publishes it, giving the illusion that Spring is reloading context files as they change.
This is useful with a small app but get's very annoying the larger your app gets.
If you're looking for this behavior for development, take a look at JRebel:
http://www.zeroturnaround.com/jrebel/

You say that you want the class to be republished ? Do you mean that you want the contents of the bean in the application context to be updated ? If that's the case, then what you can do is the following :
1) Write a file system monitor to monitor the resource(s) for changes. There's an example on google code
2) Have that file system monitor fire a custom Spring ApplicationEvent whenever the file / resource changes, providing that event the information for the resource, if necessary. ie the file name, the previous modified time, the last modified time, etc.
3) Have the bean you want to be updated implement ApplicationEventListener and reload the resource when it catches your file system monitor event.

A simple but working workaround can be to add an ant builder to your project. Steps to take:
read the article
here
http://help.eclipse.org/help33/index.jsp?topic=/org.eclipse.platform.doc.user/gettingStarted/qs-93_project_builder.htm
create a simple ant file, that
contain a target, which touches
(simply changes the date of
modification) the dependent classes,
but nothing else (if you need help in it, let me know). Eclipse will provide you variables inside the script. You can print them easily with task. You will see the list in console.
right click on the project, and
press properties
open "builders" tab in properties
add your ant script as a builder to
the project
restrict the set of resources this
ant builder is called for. This can
be done in "build options" tab in ant
builder options. This way your
project will be fast, and the ant
script will only run for the changes
of the property file
set the set of resources (classes depending on properties) to refresh after running the ant script in "Refresh" tab
Set your ant script target to be called for "Auto build" in "target" tab. Others like after and before clean and manual build should be empty
You may redirect log of the ant script to file if you want. Otherwise it will open console view.
move your builder to be the first in the list of builders, since it must run before java builder
This is a workaround, and should work. It will have no bad side effect, since the content of java file will not change, and it will not affect the version control system, as well as the whole thing is workspace independent, if the ant script is in your project.

Related

Exclude source/class file from deployment only

I'm working on a JavaFX project and there is a framework behind the scenes which handles CDI to inject a context. The problem is that the GUI is part of a bigger application and I want to be able to test it without the need to start the whole application every time. For this, I needed to update a file which is included in a dependency. I copied it to my workspace and added system properties that I can set in my launcher to fake some needed data. Until the dependency is updated to include this behavior, I need to keep the patched class in my project. The problem is, it should not be released.
So basically I want to exclude a java file from deployment but not from compilation so I can use it locally in my project.
I already tried these things:
maven-compiler-plugin: via exclusion I managed to get rid of the file but then it won't compile at all which means that I can't use its functionality in my project
copy the file to src/test/java instead - the file is not visible from the JavaFX form in the main project
maven-assembly-plugin: can't exactly get this to work the way I want it
Did I miss something or is there a way to achieve this with the assembly plugin without interrupting normal deployment?

Intellij-idea need to make and build xx.war every time when template changed?

I am new to java and spring mvc.
Because of good impression for pycharm, I choose IntelliJ Idea as my java IDE.
After some searching, I set up a debug configuration using tomcat.But I found I must make and build xx.war every time when template(.jsp file) changed , or I wouldn't see any changes in frontend .
I have never seen such situation in pycharm(python django project debug) and visual studio(.net mvc3 debug).
Is this java have to be?Or I can change some config to avoid remake?
Finally, I found the solution.
open your Tomcat Run/Debug configuration (Run > Edit Configurations)
Go to the "Deployment" tab
In the "Deploy at Server Startup" section, remove (if present) the
artifact xxx:war.
Click the add icon, select 'artifact' and then select xxx:war exploded
Then,in the Run/Debug Configuration Window, select the "Server" tab, "Update resources" or "Update Classes and Resources" will display in On 'update' action and On frame Deactivation.
Update resources: All changed resources (that is, all application components other than the classes) will be updated.
Update classes: and resources. All changed resources will be updated; changed classes will be recompiled. Note that whether the actual classes will be updated depends on the capabilities web server. If I recall, Tomcat will reload html/xhtml and jsp files, but not Servlets or classes that JSPs or Servlets use. You need to modified Tomcat to use a dynamic classloader for that.
For me who just change template to select Update resources is enough.
No, you don't need to remake and redeploy every time you make a change. However, this is primarily a tomcat question, not an intellij question.
First, you have to deploy an exploded war (you should have that option when you choose which files to deploy in the tomcat configuration box in intellij). Then you have to configure tomcat to scan for changes to jsps and recompile them. I don't know which version of tomcat you're using but you can find documentation on that on the tomcat site, or questions about achieving it here on SO.
That will only take care of the jsps though. With an exploded war static resources, such as css and javascript, should be immediately accessible after a change. It's only the need for tomcat to recompile the jsps that is causing your problem.

Eclipse doesnt update .java files

I have a little java project which is build in gradle. I imported the project to eclipse. The gradle task run starts the server and run the application in localhost(using Tomcat). Problem is, how to refresh my .java data instead of re-run the application always again. This takes time. I can change my .jsp files in build directory and after page refreshing data changes. But problem is .java files. In gradle there are task install which compile the whole project(shows errors if have), but the page content doesnt change, so i have to run project again to see the changes.
I have .class-es in 2 places. In build directory and exploded/WEB-INF. IMO, if application runs, it is using build directory files, but i dont know what files are in WEB-INF directory...
Redeployment has always been a great time consumer. There are a couple of tools(some comercial) that will help you, like JRebel. If you want to use Netbeans, there is a deploy on save option too. I don't know any other options, I'm sure there are a few more, but anyway, this should be a good start.
The easiest way is to start your application with debugger flags, then every time you update and compile your source code, the JVM will pick-up a new version automatically, without redeployment, it is called "hot-swapping".
You will need to add something similar to your run task:
-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005
Then attach Eclipse debugger to localhost:5005 and you will be good to go. It will not work if you are changing method signatures, add new class attributes or constants. Apply your changes within existing methods, then once everything works as expected, refactor and restart.
More information on debugging with Eclipse: Debugging With Eclipse Platform

Eclipse RCP - refresh PackageExplorerPart programmatically

I'm writing an eclipse plugin which contributes to the standard workbench and one action creates a new file under the current project. My problem is though, that the explorer does not refresh when the file is created in the action. What I tried so far:
((PackageExplorerPart)part).refresh(treeSelection); //where the selection is the root project
((PackageExplorerPart)part).getTreeViewer().refresh;
Both are called right after the resource is created. What am I missing? Maybe the resource is not yet merged with the explorer's model? The manual refresh reveals the file...
It depends on how you create the new file. If it is created directly in the filesystem, i.e. without using Eclipse's IResource API, you should refresh the corresponding IResource. For example, as described in refreshLocal(). That should be enough.

How to force a refresh on the Project Explorer view?

I created a Wizard that when finished, adds two files at the Project Explorer.
One of them should be hidden, but when I press the Finish button at my wizard, Eclipse doesn't refresh the view automatically and it keeps showing the file. It just hide it when I press F5.
There's a way to force it to refresh the Project Explorer, right after I finish the wizard?
Another option is in eclipse
Go to Windows-->Preferences-->General-->Workspace--> and check the box for Refresh Automatically ("refresh using native hooks or polling")
If this option is turned on then the workspace resources will be synchronized with their corresponding resources in the file system automatically.
Note: This can potentially be a lengthy operation depending on the number of resources you have in your workspace.
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.platform.doc.user/reference/ref-9.htm
It sounds like you aren't using Eclipse resources API to make file system changes. You have two options:
The best option is to use Eclipse resource API instead of java.io when working with contents of Eclipse projects. See org.eclipse.resources plugin. Start with ResourcesPlugin.getWorkspace().getRoot().getProject( "name" ). Use IProject, IFile and IFolder API.
Alternatively, especially if your wizard is invoking code that isn't eclipse-aware, you need to invoke refresh after you are sure that all java.io based file system operations have been completed. Use refreshLocal() method, which is available on IProject, IFile and IFolder classes. For instance, the following snippet refreshes all contents of a given project. This is typically an overkill, so you will want to narrow down the scope as much as possible before invoking refresh.
ResourcesPlugin.getWorkspace().getRoot().getProject( "proj" ).refreshLocal( IResource.DEPTH_INFINITE, new NullProgressMonitor() );
Another option is to use "External tools" to call your tool, and check options to refresh and maybe compile target project/s in "Refresh" and "Build" tabs.
Run -> External Tools -> Externa tools configuration

Categories

Resources