Is hot code replace supposed to work for Groovy in Eclipse? - eclipse

I was wondering if anyone was able to get Groovy hot replace working in Eclipse reliably. I can't find any useful info about this, so I am not sure if it's b/c it's just working for everyone else? Or is nobody using Eclipse to do Groovy development?
I have tried using the latest Eclipse (4.5 Mars) with latest Groovy-Eclipse plugin (Groovy Eclipse 2.9.2 from http://dist.springsource.org/snapshot/GRECLIPSE/e4.5/), and I still can't get reliable hot replace.
Some simple hot replace scenarios work fine. However, just a little bit of complexity leads to strange Groovy exceptions. I get different errors in different situations, but I was able to reproduce one in a simple junit, so I'll demonstrate that one with some simplified domain objects.
HotSwapTests.groovy:
class HotSwapTests {
#Test
public void testHotReplace() {
DefaultTxView transactionGroup = new DefaultTxView();
List<Default> defaults = [];
Default d1 = new Default(ProducerAccountTransactionType.REPAID_AMOUNT, ParticipantAccountType.DEFAULT);
Default d2 = new Default(ProducerAccountTransactionType.REPAID_AMOUNT, ParticipantAccountType.DEFAULT);
d1.setCancelledDefault(d2);
defaults << d1;
transactionGroup.setDefaultTransactions(defaults);
while (true) {
Default result = transactionGroup.getRepaymentTransaction();
println result
}
}
}
DefaultTxView.groovy:
public class DefaultTxView {
def List<Default> defaultTransactions;
public Default getRepaymentTransaction() { return getTransactionOfType(REPAID_AMOUNT); }
public Default getTransactionOfType(ProducerAccountTransactionType type) {
return defaultTransactions.find { it.getType() == type };
}
Default.java:
The contents of this domain object are not really important - it's a simple POJO.
Now, to test hotswap I place a breakpoint at the marked line:
while (true) {
Default result = transactionGroup.getRepaymentTransaction(); <<< break
println result
}
And then I go to DefaultTxView.groovy and modify the code inside the closure passed in to the find method:
public Default getTransactionOfType(ProducerAccountTransactionType type) {
return defaultTransactions.find { it.getType() == type && it.getCancelledDefault() == null};
}
I don't get any warning or error messages when I save the file, but if I attempt to step over the modified line now, I get the following exception:
java.lang.ArrayIndexOutOfBoundsException: 2
at ca.gc.agr.app.web.jsf.producer.DefaultTxView$_getTransactionOfType_closure1.doCall(DefaultTxView.groovy:15)
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.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:278)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1016)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:39)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.BooleanReturningMethodInvoker.invoke(BooleanReturningMethodInvoker.java:48)
at org.codehaus.groovy.runtime.callsite.BooleanClosureWrapper.call(BooleanClosureWrapper.java:50)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.find(DefaultGroovyMethods.java:3060)
at org.codehaus.groovy.runtime.dgm$175.invoke(Unknown Source)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:271)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at ca.gc.agr.app.web.jsf.producer.DefaultTxView.getTransactionOfType(DefaultTxView.groovy:15)
at ca.gc.agr.app.web.jsf.producer.DefaultTxView$getTransactionOfType$1.callCurrent(Unknown Source)
at ca.gc.agr.app.web.jsf.producer.DefaultTxView.getRepaymentTransaction(DefaultTxView.groovy:11)
at ca.gc.agr.app.web.jsf.producer.DefaultTxView$getRepaymentTransaction$0.call(Unknown Source)
at ca.gc.agr.app.web.jsf.temp.HotSwapTests.testHotReplace(HotSwapTests.groovy:29)
I get very similar results when running my webapp in TomCat, with the same exception after modifying that line. Restarting the junit, or TomCat makes the new line work fine, so it's definitely a hot replace issue.
So what am I doing wrong? Any advice would be appreciated.

I've used hot deploy in a web dev environment with groovy successfully in the past using the eclipse plugin.
IIRC, I used groovyReset.jar, DCEVM and jdk1.7.
groovyReset.jar should be in the classpath and set as java agent. I've used the one found inside the groovy-eclipse plugin folder (like eclipse/plugins/org.codehaus.groovy_2.3.7.xx-201411061335-e44-RELEASE/extras/groovyReset.jar)
-javaagent:/groovyReset.jar
New closures and methods were instantly visible without redeploy. Of course including a simple LOC in a method worked too. Sometimes i needed to restart the VM, but still a breath of fresh air.
In your case, i think at least groovyReset.jar must be present. It is responsible for resetting the metaclass. If you decompile a groovy class you can check method calls being called by reflection using an array of java.lang.Method. Upon hot code swap this array gets out of order, needing a reset.

Related

How to compile documents and run Jshop2 in Eclipse?

I am a student who begin to study SHOP2 from China.
My teacher told me to run JSHOP2 in Eclipse.Now I can run original zenotravel problem and generate GUI and plans.Likewise, I want to put other domain and problems to SHOP2 and produce plans.
But the problem is that I don't know how to compile them and My teacher only asked me to run the the main function in Internaldomain but it can't succeed.Follow is the original code:
public static void main(String[] args) throws Exception
{
//compile();
// compile(args);
//-- run the planning algorithm
run(args);
}
This code can run zenotravel.Then I put domain and problems named pfile1 and
tdepots respectively into SHOP2 folder.Change the codes to:
{
compile(domaintdepots);
// compile(args);
//-- run the planning algorithm
run(args);
}
It warns "domainpdfiles cannot be resolved to a variable".
Or
//--compile();
compile(args);
//-- run the planning algorithm
//run(args);
It turns out:
"Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at JSHOP2.InternalDomain.compile(InternalDomain.java:748)
at JSHOP2.InternalDomain.main(InternalDomain.java:720)"
720 is main funcition above.And 748 is compile function:
public static void compile(String[] args) throws Exception
{
//-- The number of solution plans to be returned.
int planNo = -1;
//-- Handle the number of solution plans the user wants to be returned.
if (args.length == 2 || args[0].substring(0, 2).equals("-r")) {
if (args[0].equals("-r"))
planNo = 1;
else if (args[0].equals("-ra"))
planNo = Integer.MAX_VALUE;
else try {
planNo = Integer.parseInt(args[0].substring(2));
} catch (NumberFormatException e) {
}
}
Finally,according to the advice of the friend,I put the two pddls into src folder and use “java Jshop2.InternalDomain domaintdepots”in CMD commad but an error appeared:"the main class Interdomain can't be found or loaded".But I have set the class path accurately and the Zenotravel planning can run.So how
and where can I use the command ?
And what is written in the bracket"compile()" in Eclipse?
I am also not familiar with JAVA so it's better if there is concrete instruction.Thanks a lot.
Please describe what are you trying to build, what is it supposed to do, what is the expected end result.
If you do have a valid PDDL domain and problem file, you could try to load them into the online http://editor.planning.domains/ editor using the File > Load menu. Then press the Solve button and confirm which of the file is the domain and which is problem. If the PDDL model is valid (and the underlying solver can handle the requirements), you will get a plan back.
If you are trying to build a software solution that needs a PDDL-based planning engine as one of its component, perhaps you could use one of the available implementations: https://nergmada.github.io/pddl-reference/guide/whatisplanner.html#list-of-planners
If you are trying to build your own planning engine in Java using the Eclipse IDE, you probably need a Java-based PDDL parser. Here is a tutorial, how to use pddl4j for that purpose:
https://github.com/pellierd/pddl4j/wiki/A-tutorial-to-develop-your-own-planner
If you need to use Jshop2 in particular, it looks from their documentation (http://www.cs.umd.edu/projects/shop/description.html) that you need to indeed compile the domain and problem PDDL into Java code using following commands:
java JSHOP2.InternalDomain domainFileName
java JSHOP2.InternalDomain -r problemFileName
Edited on June 19th
Java package names (e.g. JSHOP2) and class names (InternalDomain) are case sensitive, so make sure you type them as per the documentation. That is probably why you are getting the "main class not found error".
It is difficult to say what the lines numbers 748 and 720 exactly correspond to, because in the GitHub repo https://github.com/mas-group/jshop2/blob/master/src/JSHOP2/InternalDomain.java the code is different from yours. Can you indicate in your questions which lines those are exactly?
The make file shows how to execute an out-of-the-box example in the distribution:
cd examples\blocks
java JSHOP2.InternalDomain blocks
java JSHOP2.InternalDomain -r problem300
Does that work for you?

error.CannotStartupOSGIPlatform issue when running birt

I'm in the midst of implementing Birt 4.6.0 into my gwt application. Unfortunately whenever I run a specific section of the program, I get the following error:
org.eclipse.birt.core.exception.BirtException:
error.CannotStartupOSGIPlatform at
org.eclipse.birt.core.framework.Platform.startup(Platform.java:81)
I've done some searching and one thread mentioned a permissions error but I am not sure what that entails. What does this mean?
EDIT Just read another article that suggests that it may be an issue with my classpath but I already added all the jar files from ReportEngine/lib to my buildpath. Anyone know what jar files I am supposed to include?
the offending code:
public static synchronized IReportEngine getBirtEngine(ServletContext sc) {
if (birtEngine == null) {
EngineConfig config = new EngineConfig();
java.util.HashMap map = config.getAppContext();;
map.put(EngineConstants.APPCONTEXT_CLASSLOADER_KEY, SegnalazioniDbManager.class.getClassLoader());
config.setAppContext(map);
IPlatformContext context = new PlatformServletContext(sc);
config.setPlatformContext(context);
try {
Platform.startup(config); //problem begins here
.....
}
[1]: http://developer.actuate.com/community/forum/index.php?/topic/20933-errorcannotstartuposgiplatform/
Yes it is indeed a permission error.
The relevant file is:
WEB-INF/platform/configuration/org.eclipse.osgi/.manager/.fileTableLock
You need to give access to the Birt user.

Grails memory leak [duplicate]

I've found a strange issue when saving or updating several objects in Grails with MongoDB. Currently I'm using Grails 2.2.3 and MongoDB plugin 1.3.0.
The problem seems to be that the instances of MiUsuario are never GC neither when I manually call the GC. In our main application we don't make batch updates, but when doing load tests (with JMeter and monitoring JVM with Java VisualVM) this problem causes memory filling and Tomcat stops responding.
I've created a small new application to show the problem.
A simple domain object:
class MiUsuario {
ObjectId id
String nickName
}
My controller:
import pruebasrendimiento.Prueba
class MiUsuarioController {
def doLogin(String privateKey, String id){
MiUsuario user = MiUsuario.get(id)
user.nickName = new Random().nextInt().toString()
user.save(failOnError:true)
render 'ok'
}
}
My BuildConfig (Just the dependencies and plugins part):
dependencies {
}
plugins {
// runtime ":hibernate:$grailsVersion"
runtime ":jquery:1.8.3"
runtime ":resources:1.2"
build ":tomcat:$grailsVersion"
// runtime ":database-migration:1.3.2"
// compile ':cache:1.0.1'
runtime ":mongodb:1.3.0"
}
I've also tried something that Burt said a long time ago (http://burtbeckwith.com/blog/?p=73), but DomainClassGrailsPlugin.PROPERTY_INSTANCE_MAP.get().clear() doesn't make any difference. And the other option that's said in that page, RequestContextHolder.resetRequestAttributes(), gives me an exception.
I had similar problem and it solves upgrading to grails 2.3.1. Try it.

FindBugs shows only the first occurrence of a bug

FindBugs seems to show only the first occurrence of a particular bug in each method. This occurs in Eclipse as well as in the FindBugs stand-alone client.
How can I configure FindBugs to show all occurrences?
Example:
import javax.annotation.Nonnull;
public class Bar
{
public void meth(#Nonnull final String pArg) {
System.out.println(pArg);
}
public void foo() {
String s = null;
meth(s); // <<== bug marker here (NP_NONNULL_PARAM_VIOLATION)
meth(null); // no bug marker here
meth(s); // and none here either :-(
}
}
Im am using the latest FindBugs 2.0.2 Eclipse plugin (with Eclipse 3.6).
The problem appears to depend on the bug pattern. For example, I see more than one hit per method with DLS_DEAD_LOCAL_STORE, but not with NP_NONNULL_PARAM_VIOLATION. The latter is shown above.
Thanks!
It seems that Findbugs only checks those lines of code for this specific error, which can actually be reached according to a control flow analysis. With your 3 method invocations, the first one leads to a NPE, therefore the second and third will never be reached.
There have been similar bug reports for previous versions: http://sourceforge.net/p/findbugs/bugs/980/

Suppress Errors in JavaScript validation

I'm currently developing an eclipse plugin. This plugin contains a project nature which depends on the javaScript nature of jsdt.
Now at a few details the JavaScripts that the projects of my nature can contain are somewhat special.
They can contain "compiler hints" which are basicly statements beginning with #
They can contain return statements outside of functions
But at this two points the standard validation of jsdt come in and marks them as errors (which is normally right). I already managed to get this errors filtered out in the properties of the JavaScript validator (manually).
My question is, how can i exclude these errors from the validation of jsdt automatically for the projects with my nature?
JSDT uses concrete syntax parser which generates syntax errors.
You can't disable this. Only semantics error or warnings can be configured.
However you can disable entire validation of JSDT.
Below solution will suppress errors ands warnings which are generated while we save some changes on java script files. (Auto Build, Build)
Open Properties Dialog of Your Project.
Choose Builders item.
Uncheck "JavaScript Validator". And Press OK button.
Remove current errors and warnings from Problems View
This solution can't eliminate error or warning annotations in editor while you edit. They will show up on editor temporarily only when you edit it.
After a lot of research, hours of deleting markers and debugging i finally managed to delete the errors i wanted. In a bad bad way of course but i've come to a point where i just wanted this to work no matter how it's done.
If you ever want to delete existing problems that had been created during the validation process of jsdt you need to do the following (and you must not ommit anything):
Create a class extending org.eclipse.wst.jsdt.core.compiler.ValidationParticipant
Override isActive(), buildStarting() and reconcile() methods.
So there are two things you basicly have to care about.
The actual problem markers that will be created or had already been created at the end of the validation process.
The Problems created by the validation process. They are of the type CategorizedProblem and can be obtained by the ReconcileContext object that is passed to the reconcile() method.
It seems to me that the CategorizedProblems will be translated to problem markers after the validation process.
So what you need to do is:
Delete all unwanted problem markers of all files in buildStarting (this removes problem markers from all files in your project that are about to be validated)
Iterate the CategorizedProblem objects of the ReconcileContext (getProblems())
Create a new Array containing only the CategorizedProblems you want to keep
Set this new Array to the ReconcileContext with putProblems()
Delete the unwanted markers again for that file (i don't know why this is needed, please don't ask, i don't care anymore :-/)
An example implementation of such a validationParticipant could look like this: (this one will filter out problems complaining about return statements outside of methods:
[...ommited imports ...]
public class MyValidationParticipant extends org.eclipse.wst.jsdt.core.compiler.ValidationParticipant{
#Override
public boolean isActive(IJavaScriptProject project) {
return true;
}
#Override
public void buildStarting(BuildContext[] files, boolean isBatch) {
super.buildStarting(files, isBatch);
for(BuildContext context : files){
IFile file = context.getFile();
deleteUnwantedMarkers(file);
}
}
#Override
public void reconcile(ReconcileContext context) {
IResource resource = context.getWorkingCopy().getResource();
CategorizedProblem[] newProblems = new CategorizedProblem[0];
ArrayList<CategorizedProblem> newProblemList = new ArrayList<CategorizedProblem>();
CategorizedProblem[] probs = context.getProblems("org.eclipse.wst.jsdt.core.problem");
if(probs != null){
for(CategorizedProblem p : probs){
if(!(p.getMessage().equals("Cannot return from outside a function or method."))){
newProblemList.add(p);
}
}
}
}
context.putProblems("org.eclipse.wst.jsdt.core.problem", newProblemList.toArray(newProblems));
deleteUnwantedMarkers(resource);
}
public static void deleteUnwantedMarkers(IResource resource){
if(resource.isSynchronized(IResource.DEPTH_INFINITE)){
try {
IMarker[] markers = resource.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
if(markers != null && markers.length > 0){
for(IMarker m : markers){
Object message = m.getAttribute(IMarker.MESSAGE);
if(message.equals("Cannot return from outside a function or method.")){
m.delete();
}
}
}
}catch (CoreException e) {
e.printStackTrace();
}
}
}
}
As i said, this is kind of a bad solution since the code relies on the String of the error message. There should be better ways to identify the problems you don't want to have.
Don't forget to add a proper extension in your plugin.xml for the ValidationParticipant.