Bug #2483
Fix issues identified by static code analysis
100%
Related issues
History
#1 Updated by Greg Shah over 9 years ago
- Project changed from Liberty to Bugs
#2 Updated by Igor Skornyakov over 9 years ago
- Description updated (diff)
- Subject changed from Bugs project to Fix issues identified by static code analysis
#3 Updated by Igor Skornyakov over 9 years ago
1. Eclipse reports potential NPE at line 1216 in the DirectoryCopy.java
2. FindBugs reports 250+ suspicious places in P2J
#4 Updated by Igor Skornyakov over 9 years ago
1. DirectoryCopy, line 1216
if (att != null || att.length > 0)
Potential NPE. I think a correct version is: if (att != null && att.length > 0)
2. AppServerManager, line 837
appServers.remove(pool);
Argument type (AgentPool) is incompatible with the map key type (String).
A suggested change:
appServers.remove(pool.getName());
3. Bad attempt to compute absolute value of signed random integer in com.goldencode.p2j.directory.DirectoryService.closeBatchInt(DirectoryService$BatchRef, boolean, boolean) line 4728
Math.abs(new Random().nextInt())
Will not produce a negative value if new Random().nextInt() == Integer.MIN_VALUE.
A suggested change:
new Random().nextInt(Integer.MAX_VALUE)
4. Call to com.goldencode.p2j.schema.SchemaConfig$Metadata.equals(String) in com.goldencode.p2j.schema.SchemaConfig.getSchemas(boolean) [Scariest(1), High confidence] SchemaConfig.java line 125
if (metadata.equals(next))
A suggested change:
if (metadata.getName().equals(next))
5. Call to equals(null) in com.goldencode.p2j.convert.ExpressionConversionWorker.expressionType(Aast, boolean, boolean) line 1047
if ("date".equals(stype) ||
stype can only be null at this point
A suggested change: initialiaze stype as in case of PLUS above (?)
6 Call to method of static java.text.DateFormat in com.goldencode.p2j.directory.DateValue.toString() line 258.
format.format(getDate(), buf, new FieldPosition(DateFormat.YEAR_FIELD));
format is a static instance of DateFormat which is not thread-safe.
A suggested change: use ThreadLocal or make all methods using these field synchronized.
The same issue in TimeValue, LogHelper.CleanFormatter
7. A broken implementation of Object.equals() in a number of places.
The most common error is not checking for null"
com.goldencode.cache.LFUAgingCache$NodeImpl
com.goldencode.cache.LRUCache$NodeImpl
com.goldencode.expr.Expression$CacheKey
com.goldencode.expr.SymbolResolver$CacheKey
...
Suggested fix - add check for null (or, even better for instanceof).
Also - the FloatConstant.equals() implementation violates the contract making equals non-transitive.
Also - DateValue.equals() and TimeValue.equals() allow compare with instances of Calendar and Date respectively which is risky as makes equals realtion non-symmetric (contract violation).
8. Broken synchronization:
com.goldencode.p2j.net.Queue.getNodeAddress() is unsynchronized, com.goldencode.p2j.net.Queue.setNodeAddress(int) is synchronized.
com.goldencode.p2j.net.Queue.getRemoteAddress() is unsynchronized, com.goldencode.p2j.net.Queue.setRemoteAddress(int) is synchronized.
com.goldencode.p2j.security.SecurityManager.getDebugLevel() is unsynchronized, com.goldencode.p2j.security.SecurityManager.setDebugLevel(Level) is synchronized.
9.com.goldencode.p2j.ui.ColorRgb is Externalizable but doesn't define a void constructor.
It is possible to have Externalizable class w/o void constructor but it requires some additional efforts (with auxiliary class and readResolve/writeReplace - typically this trick is used for classes with final filelds). ColorRgb does not implement readResolve/writeReplace. The simplest solution is to add void constructor.
#5 Updated by Igor Skornyakov over 9 years ago
- File ias_upd20150109a.zip added
I've fixed the issues we discussed recently except the one regarding the ExpressionConversionWorker (I understand it is unclear how to deal with it).
I've removed the inconsistent synchronized clause in the com.goldencode.p2j.net.Queue as the field it protects is volatile.
In the com.goldencode.p2j.security.SecurityManager I've added ReentrantReadWriteLock to guard access to debugLevel and debugLevelRequest fields (this imposes less contention comparing to a regular monitor).
#6 Updated by Igor Skornyakov over 9 years ago
TableResultSet.java, line 603.
((BigDecimal) res).setScale(scale);
Looks like a misprint, should be: res = ((BigDecimal) res).setScale(scale);
#7 Updated by Igor Skornyakov over 9 years ago
/home/ias/p2j/src/com/goldencode/p2j/e4gl/E4GLPreprocessor.java:307 Self assignment of field E4GLPreprocessor.opts in com.goldencode.p2j.e4gl.E4GLPreprocessor.setOptions(Options)
public void setOptions(Options options)
{
this.opts = opts;
}
Should be: this.opts = options;
#8 Updated by Igor Skornyakov over 9 years ago
/home/ias/p2j/src/com/goldencode/p2j/ui/WindowWidget.java:276 There is an apparent infinite recursive loop in com.goldencode.p2j.ui.WindowWidget.setMaxWidth(NumberType).
@Override
public void setMaxWidth(NumberType maxWidth)
{
this.setMaxWidth(maxWidth);
}
Should be: this.setMaxWidthChars(maxWidth); (?)
/home/ias/p2j/src/com/goldencode/p2j/util/SocketImpl.java:1335 There is an apparent infinite recursive loop in com.goldencode.p2j.util.SocketImpl.setSocketOption(String, character).
public logical setSocketOption(String optionName, character optionVal)
{
return setSocketOption(optionName, new character(optionVal));
}
Should be (?)
#9 Updated by Igor Skornyakov over 9 years ago
/home/ias/p2j/src/com/goldencode/p2j/persist/hql/HQLParser.java:147 Incorrect lazy initialization and update of static field com.goldencode.p2j.persist.hql.HQLParser.tokenLookup in com.goldencode.p2j.persist.hql.HQLParser.lookupTokenType(String).
The tokenLookup initialization is broken for a number of reasons. If we really want to initialize it lazily it is better to use the lazy initialization holder class idiom (see. "Effective Java", 2nd edition, page 283)
A similar issue: /home/ias/p2j/src/com/goldencode/p2j/util/LogHelper.java:557 Incorrect lazy initialization and update of static field com.goldencode.p2j.util.LogHelper.fileHandler in com.goldencode.p2j.util.LogHelper.initWorker(Class)
#10 Updated by Igor Skornyakov over 9 years ago
/home/ias/p2j/src/com/goldencode/p2j/uast/CallbackResolver.java:355 Possible null pointer dereference of method in com.goldencode.p2j.uast.CallbackResolver.invokeCallback(String, Class, Class[], Object[])
The statement
return method.invoke(cb.getTargetInstance(), args);
will be invoked even if method null
Suggested fix:
return method null ? null : method.invoke(cb.getTargetInstance(), args);
#11 Updated by Igor Skornyakov over 9 years ago
/home/ias/p2j/src/com/goldencode/p2j/persist/type/DatetimeTzUserType.java:239 Possible null pointer dereference of value in com.goldencode.p2j.persist.type.DatetimeTzUserType.nullSafeSet(PreparedStatement, Object, int, SessionImplementor)
Suggested fix:
if (value == null)
{
st.setObject(index, null);
st.setObject(index + 1, null);
return;
}
#12 Updated by Igor Skornyakov over 9 years ago
/home/ias/p2j/src/com/goldencode/p2j/util/integer.java:359 Possible null pointer dereference of value in new com.goldencode.p2j.util.integer(Boolean)
The problem is with super.setValue(value) as in superclass setValue() accepts boolean. The unboxing can cause NPE.
Suggested fix: (?)
#13 Updated by Igor Skornyakov over 9 years ago
/home/ias/p2j/src/com/goldencode/p2j/util/EnvironmentOps.java:1313 Non-virtual method call in com.goldencode.p2j.util.EnvironmentOps.load(character, character, boolean) passes null for nonnull parameter of load(character, character, logical, character).
/home/ias/p2j/src/com/goldencode/p2j/util/EnvironmentOps.java:1105 Non-virtual method call in com.goldencode.p2j.util.EnvironmentOps.load(character) passes null for nonnull parameter of load(character, character, logical, character)
/home/ias/p2j/src/com/goldencode/p2j/util/EnvironmentOps.java:1121 Non-virtual method call in com.goldencode.p2j.util.EnvironmentOps.load(String) passes null for nonnull parameter of load(character, character, logical, character)
/home/ias/p2j/src/com/goldencode/p2j/util/EnvironmentOps.java:1335 Non-virtual method call in
com.goldencode.p2j.util.EnvironmentOps.load(String, character, boolean) passes null for nonnull parameter of load(character, character,
/home/ias/p2j/src/com/goldencode/p2j/util/EnvironmentOps.java:1357 Non-virtual method call in com.goldencode.p2j.util.EnvironmentOps.load(character, String, boolean) passes null for nonnull parameter of load(character, character, logical, character)
/home/ias/p2j/src/com/goldencode/p2j/util/EnvironmentOps.java:1140 Non-virtual method call in com.goldencode.p2j.util.EnvironmentOps.load(character, boolean) passes null for nonnull parameter of load(character, character, logical, character).
/home/ias/p2j/src/com/goldencode/p2j/util/EnvironmentOps.java:1379 Non-virtual method call in com.goldencode.p2j.util.EnvironmentOps.load(String, String, boolean) passes null for nonnull parameter of load(character, character, logical, character).
/home/ias/p2j/src/com/goldencode/p2j/util/EnvironmentOps.java:1159 Non-virtual method call in com.goldencode.p2j.util.EnvironmentOps.load(String, boolean) passes null for nonnull parameter of load(character, character, logical, character)
The above mentioned calls explicitly provide null as last argument (baseKey). This argument is de-referenced in the invoked static method w/o check.
Suggested fix: (?)
#14 Updated by Eric Faulhaber about 8 years ago
Igor, I'm not sure if ias_upd20150109a.zip
was ever integrated into P2J. If not, please integrate these changes into task branch 2483a now. Also go ahead and make the fixes you've suggested for the additional items you detailed above. One exception: HQLParser.java
(note 9) is generated by ANTLR, so it doesn't make sense to edit that file.
Now that you have greater familiarity with the P2J code, do you have any suggested fixes for the items above which you were not sure how to address before?
#15 Updated by Igor Skornyakov about 8 years ago
Created task branch 2483a
#16 Updated by Eric Faulhaber about 8 years ago
- Target version set to Milestone 11
#17 Updated by Igor Skornyakov about 8 years ago
I've fixed a number of issues(and some additional ones). Will commit the changes tomorrow morning after adding history records.
I've also noticed a number of issues which do not have obvious fix:
TemporaryAccountPool
uses synchronization on the apool
variable which isConcurrentLinkedQueue
.RouterSessionManager.deregisterSession
: checksqueue
variable for null after a synchronization block on itLFUAgingCache.NodeImpl
: thehits
field is modified in theaccess()
method which is invoked from the superclass constructorFloatConstant.equals
- non-transitive. The idea is understandable but the implementation obviously violates the contract. In addition there are multiple places where float point number are compared for equality. I think we need a consistent approach for this. For example we can use the approach similar to one in thejava.lang.Float.equals()
possibly ignoringAclRow.equals
- non symmetric e.g. when comparingAclRow
instance with other nonAclRow
TaggedName
.AdminLogon
- non safe assignment tologon
static field; assignment to an argument of theterminate()
method - it is a noop but a comment claims that it destroys sessionMultiClassLoader
- wrong idiom for themanagerLibsDir
lazy initializationDirectoryService
- incorrect lazy initialization of theLOG
fieldLockManager
- incorrectwhile
/wait
combination in theenterLock
method (line 131); incorrect lazy initialization of theLOG
fieldE4GLPrepocessor.setOptions
: currently is a noop. Should it bethis.opts = options
?StreamConnector.close()
-wait()
call not in a loop.ClientSpawner.spawn
- not checking return value of thelatch.await(TIME_OUT, TimeUnit.SECONDS)
. Is it correct?ReportWorker.addMatchMultiplexed
-String.replaceAll
accepts regexp as first argument butFile.separator
is usedTempTableConnection
- incorrect lazy initialization of delegate fieldGlobalEventManager
- possibleNPE
in theupdateEntityRefCount
(ifcount == null && delta <= 0
)HQLParser
- incorrect lazy initialization of thetokenLookup
;
#18 Updated by Eric Faulhaber about 8 years ago
Igor Skornyakov wrote:
TemporaryAccountPool
uses synchronization on the apool
variable which isConcurrentLinkedQueue
.
Don't know. Greg?
RouterSessionManager.deregisterSession
: checksqueue
variable for null after a synchronization block on it
This is in an assert
, and we don't normally run with asserts enabled. I guess it doesn't hurt to keep this; I would move it up just under the line which defines queue
.
LFUAgingCache.NodeImpl
: thehits
field is modified in theaccess()
method which is invoked from the superclass constructor
Intentional; please leave as is.
FloatConstant.equals
- non-transitive. The idea is understandable but the implementation obviously violates the contract. In addition there are multiple places where float point number are compared for equality. I think we need a consistent approach for this. For example we can use the approach similar to one in thejava.lang.Float.equals()
possibly ignoring
The "equality" comparisons are not direct value comparisons, but rather they are epsilon tests. Perhaps not the best solution, admittedly. Anyway, this is an old library that was repurposed to back TRPL, where I don't think we really use floating point values. I would leave this as is.
AclRow.equals
- non symmetric e.g. when comparingAclRow
instance with other nonAclRow
TaggedName
.AdminLogon
- non safe assignment tologon
static field; assignment to an argument of theterminate()
method - it is a noop but a comment claims that it destroys sessionMultiClassLoader
- wrong idiom for themanagerLibsDir
lazy initializationDirectoryService
- incorrect lazy initialization of theLOG
fieldLockManager
- incorrectwhile
/wait
combination in theenterLock
method (line 131); incorrect lazy initialization of theLOG
fieldE4GLPrepocessor.setOptions
: currently is a noop. Should it bethis.opts = options
?StreamConnector.close()
-wait()
call not in a loop.ClientSpawner.spawn
- not checking return value of thelatch.await(TIME_OUT, TimeUnit.SECONDS)
. Is it correct?ReportWorker.addMatchMultiplexed
-String.replaceAll
accepts regexp as first argument butFile.separator
is used
Not my areas of the code; anyone else have input here?
TempTableConnection
- incorrect lazy initialization of delegate field
IIRC, only one instance of TempTableConnectionProvider
is ever created, so this has been safe so far. Also, I intend to replace the use of this class soon. Nevertheless, I see your point. Looks like delegate
could be an instance variable.
GlobalEventManager
- possibleNPE
in theupdateEntityRefCount
(ifcount == null && delta <= 0
)
Yes. Suggested fix:
if (count == null) { if (delta <= 0) { throw new IllegalArgumentException("Cannot decrement ref count for unknown entity"); } count = delta; } else { count += delta; }
HQLParser
- incorrect lazy initialization of thetokenLookup
;
Generated by ANTLR; do not edit.
#19 Updated by Igor Skornyakov about 8 years ago
Eric Faulhaber wrote:
Don't know. Greg?
RouterSessionManager.deregisterSession
: checksqueue
variable for null after a synchronization block on itThis is in an
assert
, and we don't normally run with asserts enabled. I guess it doesn't hurt to keep this; I would move it up just under the line which definesqueue
.
Done.
LFUAgingCache.NodeImpl
: thehits
field is modified in theaccess()
method which is invoked from the superclass constructorIntentional; please leave as is.
I see.
FloatConstant.equals
- non-transitive. The idea is understandable but the implementation obviously violates the contract. In addition there are multiple places where float point number are compared for equality. I think we need a consistent approach for this. For example we can use the approach similar to one in thejava.lang.Float.equals()
possibly ignoringThe "equality" comparisons are not direct value comparisons, but rather they are epsilon tests. Perhaps not the best solution, admittedly. Anyway, this is an old library that was repurposed to back TRPL, where I don't think we really use floating point values. I would leave this as is.
OK. What about comparing float primitives (coordinates, sizes) for an equality (==)?
TempTableConnection
- incorrect lazy initialization of delegate fieldIIRC, only one instance of
TempTableConnectionProvider
is ever created, so this has been safe so far. Also, I intend to replace the use of this class soon. Nevertheless, I see your point. Looks likedelegate
could be an instance variable.
Thank you. I will think about that.
GlobalEventManager
- possibleNPE
in theupdateEntityRefCount
(ifcount == null && delta <= 0
)Yes. Suggested fix:
[...]
May be it better to use AtomicInteger instead of Integer? This will be more efficient. The Exception throwing you suggest doesn't seem a logical solution as we do not enforce the count
to be non-negative.
HQLParser
- incorrect lazy initialization of thetokenLookup
;Generated by ANTLR; do not edit.
OK.
#20 Updated by Greg Shah about 8 years ago
TemporaryAccountPool uses synchronization on the a pool variable which is ConcurrentLinkedQueue.
Yes, the synchronization is incorrect. I think using a separate private static Object lock = new Object();
would be sufficient.
Also note that createTemporaryAccounts()
needs to be protected with this same lock.
#21 Updated by Igor Skornyakov about 8 years ago
Greg Shah wrote:
TemporaryAccountPool uses synchronization on the a pool variable which is ConcurrentLinkedQueue.
Yes, the synchronization is incorrect. I think using a separate
private static Object lock = new Object();
would be sufficient.Also note that
createTemporaryAccounts()
needs to be protected with this same lock.
Got it. Thank you.
#22 Updated by Constantin Asofiei about 8 years ago
Igor Skornyakov wrote:
AclRow.equals
- non symmetric e.g. when comparingAclRow
instance with other nonAclRow
TaggedName
.
Sub-classes of TaggedName
may use different conditions when checking an equality - an AclRow
can't be compared to another implementation of TaggedName
. So the code is OK.
AdminLogon
- non safe assignment tologon
static field; assignment to an argument of theterminate()
method - it is a noop but a comment claims that it destroys session
I don't understand this one.
MultiClassLoader
- wrong idiom for themanagerLibsDir
lazy initialization
Yes, this can be fixed. Also, you can change the type for managerLibsDir
from String[]
to String
.
ClientSpawner.spawn
- not checking return value of thelatch.await(TIME_OUT, TimeUnit.SECONDS)
. Is it correct?
I'm not sure that this is even needed for the remote launch case:
// spawn remote BrokerSpawnResult result = cb.remoteStart(brokers, environmentMap); // wait for notification latch.await(TIME_OUT, TimeUnit.SECONDS);
The
cb.RemoteStart
will not return until the remote side finished the launch work (regardless if fail or succeed in launching).For the other case, in local start, is OK not to check, as the code doesn't care if the latch's wait time elapsed or it was notified.
#23 Updated by Igor Skornyakov about 8 years ago
Constantin Asofiei wrote:
AdminLogon
- non safe assignment tologon
static field; assignment to an argument of theterminate()
method - it is a noop but a comment claims that it destroys sessionI don't understand this one.
It is unsafe to publish the reference to this
from inside a constructor. If we need a lazy initialization of the AdminLogon
singleton there is a standard idiom for this.
The terminate()
method assigns null
to the session
argument which is noop. Are some actions are really required to destroy the session as claimed in the comment?
#24 Updated by Constantin Asofiei about 8 years ago
Igor Skornyakov wrote:
Constantin Asofiei wrote:
AdminLogon
- non safe assignment tologon
static field; assignment to an argument of theterminate()
method - it is a noop but a comment claims that it destroys sessionI don't understand this one.
It is unsafe to publish the reference to
this
from inside a constructor. If we need a lazy initialization of theAdminLogon
singleton there is a standard idiom for this.
OK, now I understand. We don't need a lazy initialization, the logon
static field is just needed to access the singleton instance from other static methods (and only if the singleton was created). It can be fixed.
The
terminate()
method assignsnull
to thesession
argument which is noop. Are some actions are really required to destroy the session as claimed in the comment?
The null
assignment should have been for the AdminLogon.session
field, not the session
parameter. Is enough to change the line from session = null;
to this.session = null;
.
#25 Updated by Igor Skornyakov about 8 years ago
Constantin Asofiei wrote:
Igor Skornyakov wrote:
Constantin Asofiei wrote:
AdminLogon
- non safe assignment tologon
static field; assignment to an argument of theterminate()
method - it is a noop but a comment claims that it destroys sessionI don't understand this one.
It is unsafe to publish the reference to
this
from inside a constructor. If we need a lazy initialization of theAdminLogon
singleton there is a standard idiom for this.OK, now I understand. We don't need a lazy initialization, the
logon
static field is just needed to access the singleton instance from other static methods (and only if the singleton was created). It can be fixed.The
terminate()
method assignsnull
to thesession
argument which is noop. Are some actions are really required to destroy the session as claimed in the comment?The
null
assignment should have been for theAdminLogon.session
field, not thesession
parameter. Is enough to change the line fromsession = null;
tothis.session = null;
.
I see. Thank you Constantin.
#26 Updated by Eric Faulhaber about 8 years ago
Igor Skornyakov wrote:
Eric Faulhaber wrote:
FloatConstant.equals
- non-transitive. The idea is understandable but the implementation obviously violates the contract. In addition there are multiple places where float point number are compared for equality. I think we need a consistent approach for this. For example we can use the approach similar to one in thejava.lang.Float.equals()
possibly ignoringThe "equality" comparisons are not direct value comparisons, but rather they are epsilon tests. Perhaps not the best solution, admittedly. Anyway, this is an old library that was repurposed to back TRPL, where I don't think we really use floating point values. I would leave this as is.
I just checked, and FloatConstant
is actually dead code. It is never referenced outside of itself. I think I implemented it long ago for completeness, in terms of the various constant types defined for the Java virtual machine specification, but I never ended up using it for the purposes of the expression compiler.
OK. What about comparing float primitives (coordinates, sizes) for an equality (==)?
This is unrelated. The use of the equality (==
) operator in TRPL code does not invoke the equals
methods defined in the constant classes in the com.goldencode.expr
package. We just use the hashCode
and equals
methods here when creating the constant pool for the class file of a dynamically compiled expression. The Compiler.assembleComparatorOp
method would assemble bytecode instructions for an actual equality test expressed in TRPL code.
#27 Updated by Igor Skornyakov about 8 years ago
Eric Faulhaber wrote:
OK. What about comparing float primitives (coordinates, sizes) for an equality (==)?
This is unrelated. The use of the equality (
==
) operator in TRPL code does not invoke theequals
methods defined in the constant classes in thecom.goldencode.expr
package. We just use thehashCode
andequals
methods here when creating the constant pool for the class file of a dynamically compiled expression. TheCompiler.assembleComparatorOp
method would assemble bytecode instructions for an actual equality test expressed in TRPL code.
I mean that we often use ==
for comparing float point data in our code (e.g. for sizes and coordinates). This looks suspicious.
#28 Updated by Eric Faulhaber about 8 years ago
Igor Skornyakov wrote:
Eric Faulhaber wrote:
GlobalEventManager
- possibleNPE
in theupdateEntityRefCount
(ifcount == null && delta <= 0
)Yes. Suggested fix:
[...]May be it better to use AtomicInteger instead of Integer? This will be more efficient. The Exception throwing you suggest doesn't seem a logical solution as we do not enforce the
count
to be non-negative.
I don't have a problem with AtomicInteger
per se, but atomicity isn't the issue here -- this private method is only called from synchronized code already. Yes, AtomicInteger
may be more efficient, though so far, this code has not manifested as a bottleneck in any profiling I've done. How would this address the possible NPE?
#29 Updated by Greg Shah about 8 years ago
I mean that we often use == for comparing float point data in our code (e.g. for sizes and coordinates). This looks suspicious.
In the places in the client where we do this, there should be comments in each location stating that it has been checked and is safe. We are supposed to only do this when the value has come from a known source (like a well known constant or where the value is known to have been cast from an integer).
If you have found any cases to the contrary, then we will want to consider those.
#30 Updated by Igor Skornyakov about 8 years ago
Eric Faulhaber wrote:
May be it better to use AtomicInteger instead of Integer? This will be more efficient. The Exception throwing you suggest doesn't seem a logical solution as we do not enforce the
count
to be non-negative.I don't have a problem with
AtomicInteger
per se, but atomicity isn't the issue here -- this private method is only called from synchronized code already. Yes,AtomicInteger
may be more efficient, though so far, this code has not manifested as a bottleneck in any profiling I've done. How would this address the possible NPE?
Well, it doesn't address the NPE issue by itself. However using of the AtomicInteger will make a check for zero reference count a little bit easier (and in a thread safe way). As I mentioned before it seems a little bit inconsistent that we reject the counter initialization with negative value but allow it to become negative later.
#31 Updated by Eric Faulhaber about 8 years ago
Igor Skornyakov wrote:
Well, it doesn't address the NPE issue by itself. However using of the AtomicInteger will make a check for zero reference count a little bit easier (and in a thread safe way). As I mentioned before it seems a little bit inconsistent that we reject the counter initialization with negative value but allow it to become negative later.
OK, please implement a solution that fixes the possible NPE as you see fit. If you want to discuss further, post it here, otherwise I'll just review the full update when ready.
#32 Updated by Igor Skornyakov about 8 years ago
Fixed the 'old' issues from this task and some of the 'new' ones. The issues from #3002 have been fixed as well (those one which are really issues).
Committed to the task branch 2483a revision 10991.
Findbugs (and Eclipse) still report a number of warnings - mostly about potential NPEs and resource leaks. The later are mostly about the situations when a resource is opened in one method and closed in another one.
#33 Updated by Igor Skornyakov about 8 years ago
The task branch 2483a was rebased from the trunk revision 10990. Committed to revision 10992.
#34 Updated by Igor Skornyakov about 8 years ago
Eric,
Should I continue fixing issues reported by Findbugs/Eclipse static code analysis?
Thank you.
#35 Updated by Eric Faulhaber about 8 years ago
Igor Skornyakov wrote:
Eric,
Should I continue fixing issues reported by Findbugs/Eclipse static code analysis?
Thank you.
If you think any are serious, then yes. Based on your earlier assessment of the remaining findings, however, it seems they do not fall into this category. I will review the task branch tonight. Thanks.
#36 Updated by Eric Faulhaber about 8 years ago
Code review 2483a/10992:
Lots of good changes. Also lots of format problems. Some comments on substance:
- I don't recognize any of the new items in
.bzrignore
. Why have these been added? - Unnecessary import statement added to
LRUCache.java
. - I don't understand the point of the changes to
Configuration
. Why is the additionalcreateConfiguration
method necessary, and why is it synchronized when it is only called from the synchronized block ingetInstance
? Also, the javadoc forcreateConfiguration
is incomplete. - Not sure about the use of
ThreadLocal
inDateValue
andTimeValue
. If these really are used across user sessions, we must useContextLocal
instead. Greg, Constantin: are these objects used across sessions? GlobalEventManager
: I agree theIllegalArgumentException
inupdateEntityRefCount
isn't necessary; I removed it.LogHelper
: useContextLocal
instead ofThreadLocal
.- I think we still want to clear the value in
integer(Boolean)
if the argument isnull
. - I expected to see changes to
FileStream
andAppServerHelper
, based on #3002-1. Were these not real issues after all?
I have made a number of adjustments and committed them to 2483a, including addressing some of the above items (though not all). Please review the changes.
Greg, Constantin: although I reviewed all the files, many of them are not ones I normally maintain. Will you please review those files you normally maintain, especially in the UI area?
Current version is 2483a/10993.
#37 Updated by Igor Skornyakov about 8 years ago
Eric Faulhaber wrote:
Code review 2483a/10992:
Lots of good changes. Also lots of format problems. Some comments on substance:
- I don't recognize any of the new items in
.bzrignore
. Why have these been added?
Sorry, I will remove them.
- Unnecessary import statement added to
LRUCache.java
.- I don't understand the point of the changes to
Configuration
. Why is the additionalcreateConfiguration
method necessary, and why is it synchronized when it is only called from the synchronized block ingetInstance
? Also, the javadoc forcreateConfiguration
is incomplete.
I've added this method because the configuration code updates the instance values may times and the existed code effectively published partially constructed object. It was possible of course to use local variable and assign the instance only when the object is completely assembled, but it looks more error prone.
I've removed the synchronized
from the createConfiguration()
method and fixed the Javadoc.
- Not sure about the use of
ThreadLocal
inDateValue
andTimeValue
. If these really are used across user sessions, we must useContextLocal
instead. Greg, Constantin: are these objects used across sessions?
The only reason to use ThreadLocal
is that format
is an instance of the non-thread safe class. As it is stateless it is safe to share it between sessions.
LogHelper
: useContextLocal
instead ofThreadLocal
.
Please see the comment above. The reason is the same.
- I think we still want to clear the value in
integer(Boolean)
if the argument isnull
.
Sorry, I do not understand. Normally we treat null
as unknown
so the value == null || value.isUnknown()
is an idiom. The existed code didn't check for null
which is a potential NPE. What do you mean by "clear the value@.?
- I expected to see changes to
FileStream
andAppServerHelper
, based on #3002-1. Were these not real issues after all?
These are not really issues. Eclipse complains about the cases when the resource (Stream or ResultSet) is created in one method ans used in the other one. I do prefer to avoid such situations but there are too many places in our code like this to fix as any such fix typically requires more or less serious logic refactoring.
Committed yo the task branch 2843a revision 10995.
I have made a number of adjustments and committed them to 2483a, including addressing some of the above items (though not all). Please review the changes.
Thank you, I'm looking on it.
#38 Updated by Igor Skornyakov about 8 years ago
Eric Faulhaber wrote:
If you think any are serious, then yes. Based on your earlier assessment of the remaining findings, however, it seems they do not fall into this category. I will review the task branch tonight. Thanks.
It is difficult to say how serious they are without a thorough analysis. In any case I believe that static code analysis and fixing should be an ongoing process.
#39 Updated by Constantin Asofiei about 8 years ago
ExpressionConversionWorker.expressionType:1056
- adding thestype = expressionType(source.getChildAt(1), infer, fuzzy);
for theMINUS
branch activates a code which was not active until now. The problem here is this: the code might have been working correctly previously, and with this, we might broke some case. Greg: any thoughts?ExpressionConversionWorker.compareClientWhereNodes
- you are changing the code fromwhile (same && (node1 != null || node2 != null))
towhile (same && (node1 != null && node2 != null))
: at least, I thinksame
should becomefalse
if one ofnode1
ornode
isnull
.KeyImport.main
- "try with resources" will close thefk
stream, so thefk.close()
is not needed in the blockConfigSyncManager
- this class is not only client-side (as it is used byConfigManager#syncConfigChanges(Runnable)
which is called on server-side widgets), so theThreadLocal
should be moved toContextLocal
. Hynek: please confirm this- the
LogicalTerminal.messageBox
change is incorrect - we need to log the message viaUnimplementedFeature.todo
, but still execute the code. You can't add thereturn
- fix in another way, i.e. asume thetitle
is empty string, if is null. PushMessagesWorker.waitForMessages
change is incorrect - the javadoc states thatthe caller must place this in a loop and check the running flag.
, which the caller does. So please revert this change or eventually remove thewaitForMessages
method and move its code into therun()
method.OverlayWindow.realize
- if theowner
isnull
, I don't think is ok to assume theownerId
is-1
- we should just return (or log a message). Hynek/Eugenie: any thoughts?integer(Boolean)
c'tor - when setting a BDT instance tounknown
, itsvalue
field should be also set tonull
, to be consistent.Utils.intersects
- are we sure we want to returntrue
if both the set arguments arenull
?
Hynek/Eugenie: please take a look at issues 4 and 7 in this note.
#40 Updated by Hynek Cihlar about 8 years ago
Constantin Asofiei wrote:
My review for 2483a rev 10995:
4ConfigSyncManager
- this class is not only client-side (as it is used byConfigManager#syncConfigChanges(Runnable)
which is called on server-side widgets), so theThreadLocal
should be moved toContextLocal
. Hynek: please confirm this
The intention was really to put the state into the thread local variable. The configuration scope is designed to work only in the scope of the current thread. If you move the state to ContextLocal
you may get into trouble when ConfigSyncManager
is run from multiple threads.
Is there any particular problem with ThreadLocal
on server?
7
OverlayWindow.realize
- if theowner
isnull
, I don't think is ok to assume theownerId
is-1
- we should just return (or log a message). Hynek/Eugenie: any thoughts?
Well, in case the owner
is null
(which must never happen for overlay windows by the way), the code int ownerId = owner != null ? owner.getId().asInt() : null
will throw an exception, due to the implicit unboxing of null
Integer
.
Let's just make the case more explicit and throw a runtime exception if owner
is null
.
#41 Updated by Constantin Asofiei about 8 years ago
Hynek Cihlar wrote:
Constantin Asofiei wrote:
My review for 2483a rev 10995:
4ConfigSyncManager
- this class is not only client-side (as it is used byConfigManager#syncConfigChanges(Runnable)
which is called on server-side widgets), so theThreadLocal
should be moved toContextLocal
. Hynek: please confirm thisThe intention was really to put the state into the thread local variable. The configuration scope is designed to work only in the scope of the current thread. If you move the state to
ContextLocal
you may get into trouble whenConfigSyncManager
is run from multiple threads.Is there any particular problem with
ThreadLocal
on server?
Thanks for clarifying, there is no problem; as you mention, the thread-local state is not needed by other threads, and all work with this data is done in only one thread. I always double-check when I see thread-local state on server-side, and I missed the Synchronization scopes don't cross thread boundaries.
note in the class javadoc.
#42 Updated by Igor Skornyakov about 8 years ago
Constantin Asofiei wrote:
My review for 2483a rev 10995:
ExpressionConversionWorker.expressionType:1056
- adding thestype = expressionType(source.getChildAt(1), infer, fuzzy);
for theMINUS
branch activates a code which was not active until now. The problem here is this: the code might have been working correctly previously, and with this, we might broke some case. Greg: any thoughts?
Actally I was confused by the Finsbugs message. Please note however that w/o this line the
if ("date".equals(stype) || "datetime".equals(stype) || "datetimetz".equals(stype)) { jcls = stype; }
doesn't make sense as
stype
is always null
.The line removed.
ExpressionConversionWorker.compareClientWhereNodes
- you are changing the code fromwhile (same && (node1 != null || node2 != null))
towhile (same && (node1 != null && node2 != null))
: at least, I thinksame
should becomefalse
if one ofnode1
ornode
isnull
.
You may be true. Please note however that if at leasy one of the nodes is null there will be NPE inside the loop body.
KeyImport.main
- "try with resources" will close thefk
stream, so thefk.close()
is not needed in the block\
Fixed.
ConfigSyncManager
- this class is not only client-side (as it is used byConfigManager#syncConfigChanges(Runnable)
which is called on server-side widgets), so theThreadLocal
should be moved toContextLocal
. Hynek: please confirm this
I haven't added ThreadLocal
to this class
- the
LogicalTerminal.messageBox
change is incorrect - we need to log the message viaUnimplementedFeature.todo
, but still execute the code. You can't add thereturn
- fix in another way, i.e. asume thetitle
is empty string, if is null.
Done.
PushMessagesWorker.waitForMessages
change is incorrect - the javadoc states thatthe caller must place this in a loop and check the running flag.
,
which the caller does. So please revert this change or eventually remove the waitForMessages
method and move its code into the run()
method.
Done.
OverlayWindow.realize
- if theowner
isnull
, I don't think is ok to assume theownerId
is-1
- we should just return (or log a message). Hynek/Eugenie: any thoughts?
Well, I'm not sure what is correct but previously null
value of the owner
caused NPE.
integer(Boolean)
c'tor - when setting a BDT instance tounknown
, itsvalue
field should be also set tonull
, to be consistent.
Sorry, I do not understand you. Isn't the value if integer
primitive?
Utils.intersects
- are we sure we want to returntrue
if both the set arguments arenull
?
Fixed.
Committed to the task branch 2483a revision 10996.
#43 Updated by Igor Skornyakov about 8 years ago
Hynek Cihlar wrote:
Well, in case the
owner
isnull
(which must never happen for overlay windows by the way), the codeint ownerId = owner != null ? owner.getId().asInt() : null
will throw an exception, due to the implicit unboxing ofnull
Integer
.Let's just make the case more explicit and throw a runtime exception if
owner
isnull
.
Done in revision 10997.
#44 Updated by Eugenie Lyzenko about 8 years ago
Igor Skornyakov wrote:
Hynek Cihlar wrote:
Well, in case the
owner
isnull
(which must never happen for overlay windows by the way), the codeint ownerId = owner != null ? owner.getId().asInt() : null
will throw an exception, due to the implicit unboxing ofnull
Integer
.Let's just make the case more explicit and throw a runtime exception if
owner
isnull
.Done in revision 10997.
Yes, the overlay owner can not be null
. The overlay window is always the feature of something. I think in such cases we must consider the main P2J window(or dialog) is the owner. This window always exists. If not - certainly is seriously wrong and we need to stop execution.
#45 Updated by Igor Skornyakov about 8 years ago
Constantin Asofiei wrote:
Igor Skornyakov wrote:
AclRow.equals
- non symmetric e.g. when comparingAclRow
instance with other nonAclRow
TaggedName
.Sub-classes of
TaggedName
may use different conditions when checking an equality - anAclRow
can't be compared to another implementation ofTaggedName
. So the code is OK.
I do not think so. If AclRow
can't be compared to another implementation of the TaggedName
why it inherits from it? I do agree with Joshua Bloch (see Effective Java
, Item 8) that violation of the contract of equal
is not a good idea. In the future this can result in bug which will be very difficult to pinpoint (including memory leaks if TaggedName
instances will be used as keys in a HashMap
. I think it is better to remove the !(o instanceof AclRow)
test in equals
(as it is done in compareTo
). At least we'll get a ClassCastException
if the assumption that the instances of AccRow
will should never be compared to instances of other classes will ever become wrong.
#46 Updated by Greg Shah about 8 years ago
My review for 2483a rev 10995:
ExpressionConversionWorker.expressionType:1056
- adding thestype = expressionType(source.getChildAt(1), infer, fuzzy);
for theMINUS
branch activates a code which was not active until now. The problem here is this: the code might have been working correctly previously, and with this, we might broke some case. Greg: any thoughts?Actally I was confused by the Finsbugs message. Please note however that w/o this line the
[...]
doesn't make sense asstype
is alwaysnull
.
The line removed.
You both make good points. If I recall, at one time we did have code to lookup stype and it may have caused an issue. I think that is why the same stype lookup only occurs in 3 of the 4 branches.
On the other hand, it is true that the comparison of stype
with "date", "datetime" and "datetimetz" will always flow down the else
branch. The original code that added this 3-part check was added (by me!) in H041 (bzr rev 10230). The bug was present at that time.
How about this: put the lookup of stype
into the if (ftype == null || "BaseDataType".equals(ftype))
section. If this does cause a problem we will see it in our testing. We need to test conversion of the customer application (both server and GUI) to ensure this is OK.
ExpressionConversionWorker.compareClientWhereNodes
- you are changing the code fromwhile (same && (node1 != null || node2 != null))
towhile (same && (node1 != null && node2 != null))
: at least, I thinksame
should becomefalse
if one ofnode1
ornode
isnull
.You may be true. Please note however that if at leasy one of the nodes is null there will be NPE inside the loop body.
I agree. Please force same
to false
if one of them is null
Not sure about the use of ThreadLocal in DateValue and TimeValue. If these really are used across user sessions, we must use ContextLocal instead. Greg, Constantin: are these objects used across sessions?
I think this is OK. We do a similar thing in date.java
.
Please note: there is a coding standards issue in both DateValue and TimeValue. The open curly brace for the ThreadLocal
needs to be on the next line.
#47 Updated by Eric Faulhaber about 8 years ago
If anyone has further contributions on any of the current items under discussion, please express those ASAP. This includes any items addressed in 2483a from #3002. We need to get the current changes into regression testing ASAP.
Igor, are you blocked on any of these, or do you have all the information you need to complete this set of fixes? I know this will be an ongoing process, but I'm just referring to the higher priority items you've addressed in task branch 2483a.
#48 Updated by Igor Skornyakov about 8 years ago
Eric Faulhaber wrote:
If anyone has further contributions on any of the current items under discussion, please express those ASAP. This includes any items addressed in 2483a from #3002. We need to get the current changes into regression testing ASAP.
Igor, are you blocked on any of these, or do you have all the information you need to complete this set of fixes? I know this will be an ongoing process, but I'm just referring to the higher priority items you've addressed in task branch 2483a.
Eric,
I do not think that I'm blocked. I plan to commit the final version of changes for those cases which are described and have a mature solution and concentrate on the the customer app environment configuration and #3035 as I understand that it has the top priority now.
#49 Updated by Igor Skornyakov about 8 years ago
The Findbugs complains about 3 places in the ScopedDictionary
class (statement foo.addAll(dictionary.entrySet())
).
Explanation:
Bug: Adding elements of an entry set may fail due to reuse of Map.Entry object in com.goldencode.p2j.util.ScopedDictionary.entrySet(int) The entrySet() method is allowed to return a view of the underlying Map in which a single Entry object is reused and returned during the iteration. As of Java 1.6, both IdentityHashMap and EnumMap did so. When iterating through such a Map, the Entry value is only valid until you advance to the next iteration. If, for example, you try to pass such an entrySet to an addAll method, things will go badly wrong.
#50 Updated by Igor Skornyakov about 8 years ago
Regarding previous note:
What's the point to use HashSet<Map.Entry<K, V>>
instead of HashMap<K,V>
?
Thank you.
#51 Updated by Igor Skornyakov about 8 years ago
Igor Skornyakov wrote:
Regarding previous note:
What's the point to useHashSet<Map.Entry<K, V>>
instead ofHashMap<K,V>
?
Thank you.
Sorry, of course instead of HashMap<K,V>
it should be HashMap<K, Set<V>>
(or Multimap<K,V>
from Google Guava)
#52 Updated by Igor Skornyakov about 8 years ago
Igor Skornyakov wrote:
The Findbugs complains about 3 places in the
ScopedDictionary
class (statementfoo.addAll(dictionary.entrySet())
).
Explanation:
[...]
Actually in my simple test the addAll(foo.EntrySet())
works fine both for EnumMap
and IdentityHashMap
(Java 8).
#53 Updated by Igor Skornyakov about 8 years ago
Finished with the next round of issues.
Committed to the task branch 2483a revision 10998.
Started regression testing.
#54 Updated by Igor Skornyakov about 8 years ago
Fixed a found.
Committed to the task branch 2483a revision 10999.
Restarted regression testing.
#55 Updated by Eric Faulhaber about 8 years ago
Igor Skornyakov wrote:
What's the point to use
HashSet<Map.Entry<K, V>>
instead ofHashMap<K,V>
?
The API in these 3 places calls for a Set<Map.Entry<K, V>>
to be returned, hence the calls to Set<Map.Entry<K, V>>.addAll(Map.entrySet())
. The point of this API is to allow the idiom:
for (Map.Entry<K, V> e : d.entrySet()) { K k = e.getKey(); V v = e.getValue(); ... }
...which is significantly less expensive than:
for (K k : d.keySet()) { V v = d.lookup(k); ... }
There is nothing that should change in these locations.
#56 Updated by Igor Skornyakov about 8 years ago
Eric Faulhaber wrote:
Igor Skornyakov wrote:
What's the point to use
HashSet<Map.Entry<K, V>>
instead ofHashMap<K,V>
?The API in these 3 places calls for a
Set<Map.Entry<K, V>>
to be returned, hence the calls toSet<Map.Entry<K, V>>.addAll(Map.entrySet())
. The point of this API is to allow the idiom:
[...]
...which is significantly less expensive than:
[...]
There is nothing that should change in these locations.
I understand. However this seems to be a little bit risky (generally speaking). Simply because Map.Entry
is not immutable and changing the the source Map
can corrupt Set
.
#57 Updated by Eric Faulhaber about 8 years ago
True, but that's the case for java.util.Map<K,V>.entrySet()
as well (after which these APIs were modelled).
#58 Updated by Igor Skornyakov about 8 years ago
Eric Faulhaber wrote:
True, but that's the case for
java.util.Map<K,V>.entrySet()
as well (after which these APIs were modelled).
That correct. But the documentation explicitly says that
These Map.Entry objects are valid only for the duration of the iteration; more formally, the behavior of a map entry is undefined if the backing map has been modified after the entry was returned by the iterator, except through the setValue operation on the map entry.
In the situation we discuss Map.Entry are used externally.
#59 Updated by Eric Faulhaber about 8 years ago
Code review 2483a/10999:
The changes look OK to me.
Greg, Constantin: please confirm the changes to your files are OK.
Igor, assuming the others are OK with the changes and regression testing is successful, please rebase to trunk rev. 10991, then merge to trunk. There is no need to re-run regression testing after that rebase.
#60 Updated by Igor Skornyakov about 8 years ago
Eric Faulhaber wrote:
Igor, assuming the others are OK with the changes and regression testing is successful, please rebase to trunk rev. 10991, then merge to trunk. There is no need to re-run regression testing after that rebase.
OK, thank you.
#61 Updated by Igor Skornyakov about 8 years ago
CTRL-C part passed OK.
#62 Updated by Igor Skornyakov about 8 years ago
From the main part the following tests failed in the first run: tc_dc_slot_026 tc_job_002 tc_job_clock_004 tc_ap_vchrs_011.
Test restarted.
#63 Updated by Constantin Asofiei about 8 years ago
TemporaryAccountPool
- you are removing the synchronization forshutDown
andpoll
andtail
. The problem here is that theTemporaryAccountWorker
is not thread-safe - only one job can be executed at a time. Your changes will allow multiple jobs to be executed concurrently, in the same instance, with unexpected results.AstGenerator
- you've backed out the changes inprepareLexer
. Is there a specific reason?- remove the copyright date/history change for
PushMessagesWorker
and any other files which no longer have changes UastHints
is missing history entryExpressionConversionWorker.compareClientWhereNodes
issue from note 39 needs to be addressed (same
becomesfalse
if either node1 or node2 is null).
#64 Updated by Igor Skornyakov about 8 years ago
Constantin Asofiei wrote:
Review for 2483a 10999:
TemporaryAccountPool
- you are removing the synchronization forshutDown
andpoll
andtail
. The problem here is that theTemporaryAccountWorker
is not thread-safe - only one job can be executed at a time. Your changes will allow multiple jobs to be executed concurrently, in the same instance, with unexpected results.
Both poll
and tail
methods work with TemporaryAccountPool.pool
which is a concurrent collection so they do not need an additional synchronization. The shoutDown
method() looks thread safe and idempotent. In fact the workerLatch.getCount() 1
check is not needed as CountDownLatch.countDown() is a noop if @CountDownLatch.getCount() 0
.
AstGenerator
- you've backed out the changes inprepareLexer
. Is there a specific reason?
The problem was that prepareLexer
publishes the created Reader
so it should not be closed.
- remove the copyright date/history change for
PushMessagesWorker
and any other files which no longer have changes
Done.
UastHints
is missing history entry
Done.
ExpressionConversionWorker.compareClientWhereNodes
issue from note 39 needs to be addressed (same
becomesfalse
if either node1 or node2 is null).
Committed to the task branch 2483a revision 11000.
#65 Updated by Constantin Asofiei about 8 years ago
Igor Skornyakov wrote:
Constantin Asofiei wrote:
Review for 2483a 10999:
TemporaryAccountPool
- you are removing the synchronization forshutDown
andpoll
andtail
. The problem here is that theTemporaryAccountWorker
is not thread-safe - only one job can be executed at a time. Your changes will allow multiple jobs to be executed concurrently, in the same instance, with unexpected results.Both
poll
andtail
methods work withTemporaryAccountPool.pool
which is a concurrent collection so they do not need an additional synchronization. TheshoutDown
method() looks thread safe and idempotent. In fact theworkerLatch.getCount() 1
check is not needed asCountDownLatch.countDown() is a noop if @CountDownLatch.getCount() 0
.
I'm not referring to the synchronization of the TemporaryAccountPool.pool
field. I'm referring to the TemporaryAccountPool.enableAccount
API, which uses the TemporaryAccountPool.poolTask.execute(core);
to execute a certain task, which is not thread-safe and needs to be synchronized: the way it is built now, TemporaryAccountWorker
can execute only a task at a time, so we need synchronization for it; otherwise, for example, the TemporaryAccountWorker.task
field may be changed in execute()
by another thread, between lines 79-83.
Also, look how TemporaryAccountWorker.workerLatch
is used: this starts initialized to 1
, and it gets re-initialized again to 1
, after each executed job, so workerLatch.countDown();
is needed, because this is how the caller gets notified the job has finished.
#66 Updated by Igor Skornyakov about 8 years ago
After the second run only tc_job_002 and tc_job_clock_004 tests failed.
Test restarted.
#67 Updated by Igor Skornyakov about 8 years ago
Constantin Asofiei wrote:
I'm not referring to the synchronization of the
TemporaryAccountPool.pool
field. I'm referring to theTemporaryAccountPool.enableAccount
API, which uses theTemporaryAccountPool.poolTask.execute(core);
to execute a certain task, which is not thread-safe and needs to be synchronized: the way it is built now,TemporaryAccountWorker
can execute only a task at a time, so we need synchronization for it; otherwise, for example, theTemporaryAccountWorker.task
field may be changed inexecute()
by another thread, between lines 79-83.
Now I understand, thank you. Fixed. BTW: if enableAccount
is a long-running operation may be it makes sense to use an single-threaded Executor
service instead of a single thread? Or at least a SynchronousQueue
if we want to avoid queue?
Also, look how
TemporaryAccountWorker.workerLatch
is used: this starts initialized to1
, and it gets re-initialized again to1
, after each executed job, soworkerLatch.countDown();
is needed, because this is how the caller gets notified the job has finished.
I was talking not about workerLatch.countDown()
but about workerLatch.getCount()== 1
check.
Committed to the task branch 2483a revision 11001.
#68 Updated by Eric Faulhaber about 8 years ago
Igor Skornyakov wrote:
CTRL-C part passed OK.
This was the first regression testing item you mentioned. However, there were a number of changes in 2483a which impact conversion. Did you run conversion regression testing first?
#69 Updated by Igor Skornyakov about 8 years ago
Eric Faulhaber wrote:
Igor Skornyakov wrote:
CTRL-C part passed OK.
This was the first regression testing item you mentioned. However, there were a number of changes in 2483a which impact conversion. Did you run conversion regression testing first?
Of course I did. And I've found and fixed a bug which affected conversion.
#70 Updated by Eric Faulhaber about 8 years ago
Constantin, AFAIK, TemporaryAccountPool
is not exercised in normal regression testing, correct? In other words, is there any reason to restart runtime regression testing with rev. 11001? Is there a manual test we can use to regression test this feature?
#71 Updated by Constantin Asofiei about 8 years ago
Eric Faulhaber wrote:
Constantin, AFAIK,
TemporaryAccountPool
is not exercised in normal regression testing, correct? In other words, is there any reason to restart runtime regression testing with rev. 11001? > Is there a manual test we can use to regression test this feature?
No, TemporaryAccountPool
is not used by normal testing. This is used for appserver agent startup and also for GUI Web clients - ensuring these both work should be enough.
Igor, please add the {
on a new line, in TemporaryAccountPool
changes you've added, related to this:
synchronized (taskLock) {
#72 Updated by Igor Skornyakov about 8 years ago
Constantin Asofiei wrote:
Constantin, AFAIK,
TemporaryAccountPool
is not exercised in normal regression testing, correct? In other words, is there any reason to restart runtime regression testing with rev. 11001? > Is there a manual test we can use to regression test this feature?No,
TemporaryAccountPool
is not used by normal testing. This is used for appserver agent startup and also for GUI Web clients - ensuring these both work should be enough.
The web client is working.
Igor, please add the
{
on a new line, inTemporaryAccountPool
changes you've added, related to this:
[...]
Fixed.
Committed to the task branch 2483a revision 11002
#73 Updated by Igor Skornyakov about 8 years ago
Only tc_job_002
test failed after 3 runs of the main-regression
.
The task branch 2483a was rebased from the trunk revision 10991. Committed to revision 11003.
Can I merge it to the trunk?
Thank you.
#74 Updated by Eric Faulhaber about 8 years ago
Igor Skornyakov wrote:
Can I merge it to the trunk?
Was the change you made today (rev. 11001) to ExpressionConversionWorker
made before or after conversion regression testing passed? If after, you will need to run (only) conversion regression testing against the newest build. If before, then yes, please merge to trunk.
#75 Updated by Igor Skornyakov about 8 years ago
Eric Faulhaber wrote:
Was the change you made today (rev. 11001) to
ExpressionConversionWorker
made before or after conversion regression testing passed? If after, you will need to run (only) conversion regression testing against the newest build. If before, then yes, please merge to trunk.
This change was made before the regression test conversion.
Regression test conversion restarted
#76 Updated by Igor Skornyakov about 8 years ago
Majic code conversion and build with the task branch 2483a finished OK.
#77 Updated by Eric Faulhaber about 8 years ago
Great! Please merge to trunk.
#78 Updated by Igor Skornyakov about 8 years ago
Merged and committed to the trunk revision 10992.
Task branch 2483a archived
#79 Updated by Eric Faulhaber about 8 years ago
- Status changed from New to Closed
- % Done changed from 0 to 100
Since all of the potential defects from this round of static code analysis that were deemed worthwhile to address have been fixed, I am closing this issue. Any future issues will be addressed separately, rather than keeping this issue open indefinitely.
#80 Updated by Greg Shah over 7 years ago
- Target version changed from Milestone 11 to Cleanup and Stablization for Server Features