Does EL support overloaded methods? - el

I upgraded my Java EE web application to use newer PrimeFaces version and suddenly the call of an overloaded bean method in an action attribute of PrimeFaces commandlink did not work anymore. I tried to use JSF default commandlink to test it and this one did not work either.
The method signatures are as follows:
public void updateA(B b);
public void updateA(A a);
It always tried to cast A to B.
More curious, how could it work before the upgrade?

EL does not support it, no. It'll always be the first method of the Class#getMethods() array whose name (and amount of arguments) matches the EL method call. Whether it returns the same method everytime or not depends on the JVM make/version used. Perhaps you made a Java SE upgrade in the meanwhile as well. The javadoc even says this:
The elements in the array returned are not sorted and are not in any particular order.
You should not rely on unspecified behaviour. Give them a different name.

The way you can get around this is to create a generic method and do the 'routing' inside that method. I know that this might not be ideal, but you end up with less configurations in functions and XHTML pages.
if (A.class.isInstance(obj)) {
A o = (A) obj;
return method(o, highRes);
} else if (B.class.isInstance(obj)) {
B o = (B) obj;
return method(o, highRes);
} else if (C.class.isInstance(obj)) {
C o = (C) obj;
return method(o, highRes);
} else {
throw new FacesException("Unsupported Conversion: " + obj);
}

Related

What is the analogue of Mockito.verifyZeroInteractions(obj) in the Mockk library?

I want to switch to Mockk, but i cant find analogue of this method in Mockk
It doesn't work
verify (exactly = 0) { obj }
The way you are trying it, is missing the method or variable
verify (exactly = 0) { obj.something }
Using the exactly zero approach would require
confirmVerified(obj)
To be sure nothing else was called.
The exact equivalent would be:
verify { obj wasNot Called }

ABP: Value cannot be null. (Parameter 'unitOfWork')

I upgraded my abp version from 3.5.0 to 7.0.0.
I set method’s attribute UnitOfWork[IsDisabled = true].
Then I run the code like:
xxRepository.GetAllList()
I get the exception:
Value cannot be null. (Parameter 'unitOfWork').
Why? Why not support getalllist in a disabled unitofwork any more? In this case how can I update 1,000,000 data in a loop?
ABP v6.4 introduced a breaking change with the removal of conventional interceptors (for IRepository and IApplicationService) in Minimize interception usage #6165 with an option to allow disabling the removal of conventional interceptors.
You should begin a unit of work explicitly:
using (var uow = unitOfWorkManager.Begin())
{
xxs = xxRepository.GetAllList();
uow.Complete();
}
You can restore the previous behaviour, though this option may be removed in a later version:
return services.AddAbp<AbpProjectNameWebTestModule>(options =>
{
options.SetupTest();
// }); // Change this
}, removeConventionalInterceptors: false); // to this
[UnitOfWork(IsDisabled = true)]
public virtual void RemoveFriendship(RemoveFriendshipInput input)
{
_friendshipRepository.Delete(input.Id);
}
Note that if a unit of work method calls this RemoveFriendship method, disabling this method is ignored, and it will use the same unit of work with the caller method. So, disable carefully! The code above works well since the repository methods are a unit of work by default.
In addition, maybe even disabling the transaction may be sufficient.
References:
https://aspnetboilerplate.com/Pages/Documents/Unit-Of-Work#disabling-unit-of-work
https://aspnetboilerplate.com/Pages/Documents/Unit-Of-Work#non-transactional-unit-of-work
https://github.com/aspnetboilerplate/aspnetboilerplate/issues/648

Optaplanner: NullPointerException when calling scoreDirector.beforeVariableChanged in a simple custom move

I am building a Capacited Vehicle Routing Problem with Time Windows, but with one small difference when compared to the one provided in examples from the documentation: I don't have a depot. Instead, each order has a pickup step, and a delivery step, in two different locations.
(like in the Vehicle Routing example from the documentation, the previousStep planning variable has the CHAINED graph type, and its valueRangeProviderRefs includes both Drivers, and Steps)
This difference adds a couple of constraints:
the pickup and delivery steps of a given order must be handled by the same driver
the pickup must be before the delivery
After experimenting with constraints, I have found that it would be more efficient to implement two types of custom moves:
assign both steps of an order to a driver
rearrange the steps of a driver
I am currently implementing that first custom move. My solver's configuration looks like this:
SolverFactory<RoutingProblem> solverFactory = SolverFactory.create(
new SolverConfig()
.withSolutionClass(RoutingProblem.class)
.withEntityClasses(Step.class, StepList.class)
.withScoreDirectorFactory(new ScoreDirectorFactoryConfig()
.withConstraintProviderClass(Constraints.class)
)
.withTerminationConfig(new TerminationConfig()
.withSecondsSpentLimit(60L)
)
.withPhaseList(List.of(
new LocalSearchPhaseConfig()
.withMoveSelectorConfig(CustomMoveListFactory.getConfig())
))
);
My CustomMoveListFactory looks like this (I plan on migrating it to an MoveIteratorFactory later, but for the moment, this is easier to read and write):
public class CustomMoveListFactory implements MoveListFactory<RoutingProblem> {
public static MoveListFactoryConfig getConfig() {
MoveListFactoryConfig result = new MoveListFactoryConfig();
result.setMoveListFactoryClass(CustomMoveListFactory.class);
return result;
}
#Override
public List<? extends Move<RoutingProblem>> createMoveList(RoutingProblem routingProblem) {
List<Move<RoutingProblem>> moves = new ArrayList<>();
// 1. Assign moves
for (Order order : routingProblem.getOrders()) {
Driver currentDriver = order.getDriver();
for (Driver driver : routingProblem.getDrivers()) {
if (!driver.equals(currentDriver)) {
moves.add(new AssignMove(order, driver));
}
}
}
// 2. Rearrange moves
// TODO
return moves;
}
}
And finally, the move itself looks like this (nevermind the undo or the isDoable for the moment):
#Override
protected void doMoveOnGenuineVariables(ScoreDirector<RoutingProblem> scoreDirector) {
assignStep(scoreDirector, order.getPickupStep());
assignStep(scoreDirector, order.getDeliveryStep());
}
private void assignStep(ScoreDirector<RoutingProblem> scoreDirector, Step step) {
StepList beforeStep = step.getPreviousStep();
Step afterStep = step.getNextStep();
// 1. Insert step at the end of the driver's step list
StepList lastStep = driver.getLastStep();
scoreDirector.beforeVariableChanged(step, "previousStep"); // NullPointerException here
step.setPreviousStep(lastStep);
scoreDirector.afterVariableChanged(step, "previousStep");
// 2. Remove step from current chained list
if (afterStep != null) {
scoreDirector.beforeVariableChanged(afterStep, "previousStep");
afterStep.setPreviousStep(beforeStep);
scoreDirector.afterVariableChanged(afterStep, "previousStep");
}
}
The idea being that at no point I'm doing an invalid chained list manipulation:
However, as the title and the code comment indicate, I am getting a NullPointerException when I call scoreDirector.beforeVariableChanged. None of my variables are null (I've printed them to make sure). The NullPointerException doesn't occur in my code, but deep inside Optaplanner's inner workings, making it difficult for me to fix it:
Exception in thread "main" java.lang.NullPointerException
at org.drools.core.common.NamedEntryPoint.update(NamedEntryPoint.java:353)
at org.drools.core.common.NamedEntryPoint.update(NamedEntryPoint.java:338)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.update(StatefulKnowledgeSessionImpl.java:1579)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.update(StatefulKnowledgeSessionImpl.java:1551)
at org.optaplanner.core.impl.score.stream.drools.DroolsConstraintSession.update(DroolsConstraintSession.java:49)
at org.optaplanner.core.impl.score.director.stream.ConstraintStreamScoreDirector.afterVariableChanged(ConstraintStreamScoreDirector.java:137)
at org.optaplanner.core.impl.domain.variable.inverserelation.SingletonInverseVariableListener.retract(SingletonInverseVariableListener.java:96)
at org.optaplanner.core.impl.domain.variable.inverserelation.SingletonInverseVariableListener.beforeVariableChanged(SingletonInverseVariableListener.java:46)
at org.optaplanner.core.impl.domain.variable.listener.support.VariableListenerSupport.beforeVariableChanged(VariableListenerSupport.java:170)
at org.optaplanner.core.impl.score.director.AbstractScoreDirector.beforeVariableChanged(AbstractScoreDirector.java:430)
at org.optaplanner.core.impl.score.director.AbstractScoreDirector.beforeVariableChanged(AbstractScoreDirector.java:390)
at test.optaplanner.solver.AssignMove.assignStep(AssignMove.java:98)
at test.optaplanner.solver.AssignMove.doMoveOnGenuineVariables(AssignMove.java:85)
at org.optaplanner.core.impl.heuristic.move.AbstractMove.doMove(AbstractMove.java:35)
at org.optaplanner.core.impl.heuristic.move.AbstractMove.doMove(AbstractMove.java:30)
at org.optaplanner.core.impl.score.director.AbstractScoreDirector.doAndProcessMove(AbstractScoreDirector.java:187)
at org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider.doMove(LocalSearchDecider.java:132)
at org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider.decideNextStep(LocalSearchDecider.java:116)
at org.optaplanner.core.impl.localsearch.DefaultLocalSearchPhase.solve(DefaultLocalSearchPhase.java:70)
at org.optaplanner.core.impl.solver.AbstractSolver.runPhases(AbstractSolver.java:98)
at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:189)
at test.optaplanner.OptaPlannerService.testOptaplanner(OptaPlannerService.java:68)
at test.optaplanner.App.main(App.java:13)
Is there something I did wrong? It seems I am following the documentation for custom moves fairly closely, outside of the fact that I am using exclusively java code instead of drools.
The initial solution I feed to the solver has all of the steps assigned to a single driver. There are 15 drivers and 40 orders.
In order to bypass this error, I have tried a number of different things:
remove the shadow variable annotation, turn Driver into a problem fact, and handle the nextStep field myself => this makes no difference
use Simulated Annealing + First Fit Decreasing construction heuristics, and start with steps not assigned to any driver (this was inspired by looking up the example here, which is more complete than the one from the documentation) => the NullPointerException appears on afterVariableChanged instead, but it still appears.
a number of other things which were probably not very smart
But without a more helpful error message, I can't think of anything else to try.
Thank you for your help

In SourceMod, how do I check if a plugin exists?

In SourceMod, how do I check if a plugin exists? I tried the GetFeatureStatus method, but it doesn't work. Any ideas?
If a plugin has registered itself as a Library, you can check if it exists using the LibraryExists command on the name it registered. Traditionally, this name is in all lowercase, but some plugins/extensions use mixed-case, such as SteamTools (which uses "SteamTools").
Having said that, it's generally better to cache whether a library exists instead of constantly calling this command... but then a library can be unloaded or loaded on your without your knowledge. There are functions to catch that.
So, the best way is generally to do something like this (using the NativeVotes plugin as an example).
#undef REQUIRE_PLUGIN
#include <nativevotes>
//global variable
new bool:g_bNativeVotes = false;
public OnAllPluginsLoaded()
{
g_bNativeVotes = LibraryExists("nativevotes");
}
public OnLibraryAdded(const String:name[])
{
if (StrEqual(name, "nativevotes"))
{
g_bNativeVotes = true;
}
}
public OnLibraryRemoved(const String:name[])
{
if (StrEqual(name, "nativevotes"))
{
g_bNativeVotes = false;
}
}
If a plugin isn't registered as a library, you can use GetFeatureStatus to check for a particular native. The catch is in realizing that this function doesn't return a bool, but rather a FeatureStatus_ value.
For instance, here's how I'd check for a (in development) feature for the same plugin as mentioned above:
if (GetFeatureStatus(FeatureType_Native, "NativeVotes_IsVoteCommandRegistered") == FeatureStatus_Available)
{
// Do something with vote commands.
}

How do I express a void method call as the result of DynamicMetaObject.BindInvokeMember?

I'm trying to give a short example of IDynamicMetaObjectProvider for the second edition of C# in Depth, and I'm running into issues.
I want to be able to express a void call, and I'm failing. I'm sure it's possible, because if I dynamically call a void method using the reflection binder, all is fine. Here's a short but complete example:
using System;
using System.Dynamic;
using System.Linq.Expressions;
class DynamicDemo : IDynamicMetaObjectProvider
{
public DynamicMetaObject GetMetaObject(Expression expression)
{
return new MetaDemo(expression, this);
}
public void TestMethod(string name)
{
Console.WriteLine(name);
}
}
class MetaDemo : DynamicMetaObject
{
internal MetaDemo(Expression expression, DynamicDemo demo)
: base(expression, BindingRestrictions.Empty, demo)
{
}
public override DynamicMetaObject BindInvokeMember
(InvokeMemberBinder binder, DynamicMetaObject[] args)
{
Expression self = this.Expression;
Expression target = Expression.Call
(Expression.Convert(self, typeof(DynamicDemo)),
typeof(DynamicDemo).GetMethod("TestMethod"),
Expression.Constant(binder.Name));
var restrictions = BindingRestrictions.GetTypeRestriction
(self, typeof(DynamicDemo));
return new DynamicMetaObject(target, restrictions);
}
}
class Test
{
public void Foo()
{
}
static void Main()
{
dynamic x = new Test();
x.Foo(); // Works fine!
x = new DynamicDemo();
x.Foo(); // Throws
}
}
This throws an exception:
Unhandled Exception:
System.InvalidCastException: The
result type 'System.Void' of the
dynamic binding produced by the object
with type 'DynamicDemo' for the binder
'Microsoft.CSharp.RuntimeBinder.CSharpInvokeMemberBinder'
is not compatible with the result type 'System.Object' expected by the
call site.
If I change the method to return object and return null, it works fine... but I don't want the result to be null, I want it to be void. That works fine for the reflection binder (see the first call in Main) but it fails for my dynamic object. I want it to work like the reflection binder - it's fine to call the method, so long as you don't try to use the result.
Have I missed a particular kind of expression I can use as the target?
This is similar to:
DLR return type
You do need to match the return type specified by the ReturnType property. For all of the standard binaries this is fixed to object for almost everything or void (for the deletion operations). If you know you're making a void call I'd suggest wrapping it in:
Expression.Block(
call,
Expression.Default(typeof(object))
);
The DLR used to be quite lax about what it would allow and it would provide some minimal amount of coercion automatically. We got rid of that because we didn't want to provide a set of convensions which may or may not have made sense for each language.
It sounds like you want to prevent:
dynamic x = obj.SomeMember();
There's no way to do that, there'll always be a value returned that the user can attempt to continue to interact with dynamically.
I don't like this, but it seems to work; the real problem seems to be the binder.ReturnType coming in oddly (and not being dropped ("pop") automatically), but:
if (target.Type != binder.ReturnType) {
if (target.Type == typeof(void)) {
target = Expression.Block(target, Expression.Default(binder.ReturnType));
} else if (binder.ReturnType == typeof(void)) {
target = Expression.Block(target, Expression.Empty());
} else {
target = Expression.Convert(target, binder.ReturnType);
}
}
return new DynamicMetaObject(target, restrictions);
Perhaps the callsite expects null to be returned but discards the result - This enum looks interesting, particularly the "ResultDiscarded" flag...
[Flags, EditorBrowsable(EditorBrowsableState.Never)]
public enum CSharpBinderFlags
{
BinaryOperationLogical = 8,
CheckedContext = 1,
ConvertArrayIndex = 0x20,
ConvertExplicit = 0x10,
InvokeSimpleName = 2,
InvokeSpecialName = 4,
None = 0,
ResultDiscarded = 0x100,
ResultIndexed = 0x40,
ValueFromCompoundAssignment = 0x80
}
Food for thought...
UPDATE:
More hints can be gleaned from Microsoft / CSharp / RuntimeBinder / DynamicMetaObjectProviderDebugView which is used (I presume) as a visualizer for debuggers. The method TryEvalMethodVarArgs examines the delegate and creates a binder with the result discarded flag (???)
Type delegateType = Expression.GetDelegateType(list.ToArray());
if (string.IsNullOrEmpty(name))
{
binder = new CSharpInvokeBinder(CSharpCallFlags.ResultDiscarded, AccessibilityContext, list2.ToArray());
}
else
{
binder = new CSharpInvokeMemberBinder(CSharpCallFlags.ResultDiscarded, name, AccessibilityContext, types, list2.ToArray());
}
CallSite site = CallSite.Create(delegateType, binder);
... I'm at the end of my Reflector-foo here, but the framing of this code seems a bit odd since the TryEvalMethodVarArgs method itself expects an object as a return type, and the final line returns the result of the dynamic invoke. I'm probably barking up the wrong [expression] tree.
-Oisin
The C# binder (in Microsoft.CSharp.dll) knows whether or not the result is used; as x0n (+1) says, it keeps track of it in a flag. Unfortunately, the flag is buried inside a CSharpInvokeMemberBinder instance, which is a private type.
It looks like the C# binding mechanism uses ICSharpInvokeOrInvokeMemberBinder.ResultDiscarded (a property on an internal interface) to read it out; CSharpInvokeMemberBinder implements the interface (and property). The job appears to be done in Microsoft.CSharp.RuntimeBinder.BinderHelper.ConvertResult(). That method has code that throws if the aforementioned ResultDiscarded property doesn't return true if the type of the expression is void.
So it doesn't look to me like there's an easy way to tease out the fact that the result of the expression is dropped from the C# binder, in Beta 2 at least.