After upgrading to Intershop CM 7.10.18.1, we are getting NullPtr exceptions while opening store detail page in backoffice.
ISML template for store details is EditStore_52.isml, which includes ISCountrySelectBox module, which futhermore calls getCountryNamesAndCodes() method.
That method fails with NullPtr exception because of underlined call which returns null.
We are wondering whether this is a bug and whether the intended code was supposed to be:
countriesMap.put(country.getId(), country.getDisplayName(currentLocale));
Please advise on workaround for this situation.
The following is a stack trace for exception.
Intershop delivers address data which can be imported/export through Operations backoffice (e.g. Login at https://localhost:8443/INTERSHOP/web/WFS/SLDSystem using Organization Operations). Out of the box such address data looks like this:
<country>
<id>DE</id>
<custom-attributes>
<custom-attribute dt:dt="string" name="displayName" xml:lang="de-DE">Deutschland</custom-attribute>
<custom-attribute dt:dt="string" name="displayName" xml:lang="fr-FR">Allemagne</custom-attribute>
<custom-attribute dt:dt="string" name="displayName" xml:lang="en-US">Germany</custom-attribute>
</custom-attributes>
</country>
As you can see, it only contains displayName attribute values for de-DE, fr-FR and en-US. A possible workaround in your case would be to export data, include missing attribute values and import it again.
Please note: The work to deliver a fix for this is already in progress. I'm sorry for the inconvenience.
The more convenient way (because editing xml import files is tedious) would be to replace the erroneous implementation using guice module override. In a nutshell:
Copy paste the original implementation of class com.intershop.component.region.internal.geoobject.LocalizedCountryNamesProviderImpl into a class of your own in your custom cartridge. For example: I just created a class AppSFLocalizedCountryNamesProviderImpl in cartridge app_sf_responsive to test this.
Adapt above method according to your needs
Create an override module (See Cookbook - Dependency Injection and ObjectGraphs). Following my example the modules configure operation should look like this:
#Override
protected void configure()
{
bind(LocalizedCountryNamesProvider.class).to(AppSFLocalizedCountryNamesProviderImpl.class);
bindProvider(com.intershop.component.foundation.capi.localization.LocalizedCountryNamesProvider.class)
.to(AppSFLocalizedCountryNamesProviderImpl.class);
}
Publish your cartridge, Restart your server
Related
I am attempting to migrate from version 3.2.0 to 3.3.0. I am getting a compile error. I could not find an entry in the "Breaking Changes" section but here are my two errors in hope someone can guide me to a workable alternative.
public void RegisterTypeSingleton<T>(Type component, string name)
{
if (_container.Kernel.HasComponent(name))
_container.Kernel.RemoveComponent(name);
_container.Register(Component.For<T>().ImplementedBy(component).Named(name).LifeStyle.Singleton);
}
It seems Kernel.RemoveComponent() function has been depreciated. What has replaced this?
The second compiler error is at _container.Register(Component.For<T>().ImplementedBy(component).Named(name).LifeStyle.Singleton);
I am getting "The Type 'TService' must be a reference type in order to use it as a parameter.
I think you might be upgrading from an older version than 3.2.0. See below.
The removal of IKernel.RemoveComponent() is documented in the Breaking Changes document with v3.0.0. Here is the extract where Krzysztof explains why it was removed:
change - Removed the following methods:
GraphNode.RemoveDepender,
GraphNode.RemoveDependent,
IKernel.RemoveComponent,
IKernelEvents.ComponentUnregistered,
INamingSubSystem.this[Type service],
INamingSubSystem.GetHandler,
INamingSubSystem.GetService2Handler,
INamingSubSystem.GetKey2Handler,
INamingSubSystem.UnRegister(String key),
INamingSubSystem.UnRegister(Type service)
Also INamingSubSystem.Register now takes only IHandler as its argument
impact - low
fixability - none
description - The methods were implementation of "remove component from the container" feature
which was flawed and problematic, hecen was scraped.
fix - Working around is quite dependant on your specific usage. Try utilizing IHandlerSelectors.
For changed Register method, just update your calling code not to pass the name.
handler.ComponentModel.Name is now used as the key, as it was happening in all places so far
anyway, so this change should have no real impact.
RegisterComponent() won't overwrite an existing service registration, it'll just register another component for the same service, unless you specify the same name where it'll throw an exception informing you there is another component registered with that name. If your application doesn't replace components very often you could use the IsDefault() method on the registration to get Windsor to resolve the new component by default, just note the other component is still registered.
If your application replaces components often and you don't want the other registrations left there, you'd be best using a custom IHandlerSelector or ISubDependencyResolver so Windsor will ask you each time what component you want used for a specific service.
Also in v3.0.0 a change was made to ensure that value types cannot be passed to the registration methods. You'll need to add a generic constraint to your method that accepts a generic parameter so that it also only accepts reference types:
public void RegisterTypeSingleton<T>(Type component, string name)
where T : class
{
...
}
I am working on struts 2.0 . I am designing a web application.
I am using Jasper Report in my application. I want to access the *.jrxml files in my action class. I don't want to give hard coded path to the files. So to get the path dynamically I googled it and got the solution that I can get the path using getRealPath() method. But I found two implementation of doing this:
Using HttpSession to get object of ServletContext and using the getRealPath() method of the ServletContext object.
Like this:
HttpSession session = request.getSession();
String realPath = session.getServletContext().getRealPath("/");
The second approach to do it directly using the static method getServletContext() of ServletActionContext. And then we can get the real path of the application using the getRealPath() method.
Like this:
String realPath = ServletActionContext.getServletContext().getRealPath("/");
Please tell me, is there any difference between the above two and also please tell me whether there is any other way to get the path?
Neither is "better", really, and I'd argue that neither is particularly good, either.
I might try getting the context path in an initialization servlet and stick it into the application context, then make your action(s) ApplicationAware and retrieve the value from the map.
This has the added benefit of aiding testability and removing the static references in the action.
That said, I see zero reason to go through the extra mechanics of your first approach: it adds a lot of noise for no perceivable benefit; I'm not even sure why it wuld be considered.
I'd also be a little wary of tying your actions to a path like this unless there's a real need, what's the specific use? In general you shouldn't need to access intra-app resources by their path.
Flash builder lets me insert metadata for events fired by a class, example:
[Event("myEvent", "flash.events.Event")]
public class MyClass() {
}
Is there any way to do the same for Exceptions?
Currently I have checked here, and can't see it documented. Perhaps it's not even worthwhile, what are your thoughts.
There are ways to create your own metadata; and add that into your app at compile time. Use the keep-as3-metadata compiler argument.
It will be up to you to write code to do something with it at runtime; or to build IDE extensions to make use of the code while writing the code.
To access such metadata at runtime, you'll need to perform some type of introspection. Here are some docs and another StackOverflow Question about this.
Many Flex Frameworks make use of custom metadata.
In my SharePoint code, I have the following line:
SPWeb web = site.RootWeb; //site is an SPSite object
When I rebuild my project and run the SPDispose tool on the assembly, I get the following error:
Module: Blah.SharePoint.Features.Core.dll Method:
Blah.SharePoint.Features.Core.Helpers.FeatureDeploymentHelper.RemoveWebPartFiles(Microsoft.SharePoint.SPFeatureReceiverProperties,System.String)
Statement: web := site.{Microsoft.SharePoint.SPSite}get_RootWeb()
Source:
C:\xxx\xxx\Main\Source\SharePoint\Features\Core\Helpers\FeatureDeploymentHelper.cs
Line: 26
Notes: Disposable type not disposed: Microsoft.SharePoint.SPWeb
***This may be a false positive depending on how the type was created or if it is disposed outside the current scope More Information:
http://blogs.msdn.com/rogerla/archive/2008/02/12/sharepoint-2007-and-wss-3-0-dispose-patterns-by-example.aspx#SPDisposeCheckID_140
What I want to do is to have the SPDispose tool ignore this error, so I have pulled the SPDisposeCheckIgnore class and supporting enum into my project, and I've decorated my method appropriately:
[SPDisposeCheckIgnore(SPDisposeCheckID.SPDisposeCheckID_140, "RootWeb does not need disposed.")]
public static void RemoveWebPartFiles(SPFeatureReceiverProperties properties, string assemblyName)
{
...
}
After doing all of this, I still receive the error. Anyone know how I might go about getting rid of that error?
Two things need to be done here.
1) The SPDisposeCheckIgnore class must be defined in the SPDisposeCheck namespace. You CANNOT have your own namespace. See the related comment on this page: http://archive.msdn.microsoft.com/SPDisposeCheck/
2) Anything you are trying to ignore within RunWithElevatedPrivleges must be pulled into an external method or it will not be recognized. This was not being done in the example above, but was being done in other places.
These two rules must be followed for ignore to work. Hope this helps someone else down the road.
Double check how you're retrieving and assigning the RootWeb object. If it's done in an external method, the DisposeChecker might not pick up that it's a RootWeb reference.
I don't see anything wrong with what you've written. I pulled out getting the root web into a static method so I only had to ignore this error in one place, and it works in anonymous delegates. The following worked for me:
public class DisposeUtils
{
[SPDisposeCheckIgnore(SPDisposeCheckID.SPDisposeCheckID_140, "RootWeb does not need disposed. http://blogs.msdn.com/b/rogerla/archive/2009/11/30/sharepoint-2007-2010-do-not-dispose-guidance-spdisposecheck.aspx")]
public static SPWeb GetRootWeb(SPSite site)
{
return site.RootWeb;
}
}
Sorry, I'm not sure if that helps exactly - I'm saying your code should work. Have you checked SPDisposeCheck to see how it handles 'Documented' and 'Undocumented' errors? (I've never been entirely clear what those settings do)
I am creating a custom route by subclassing RouteBase. I have a dependency in there that I'd like to wire up with IoC. The method GetRouteData just takes HttpContext, but I want to add in my unit of work as well....somehow.
I am using StructureMap, but info on how you would do this with any IoC framework would be helpful.
Well, here is our solution. Many little details may be omitted but overall idea is here. This answer may be a kind of offtop to original question but it describes the general solution to the problem.
I'll try to explain the part that is responsible for plain custom HTML-pages that are created by users at runtime and therefore can't have their own Controller/Action. So the routes should be either somehow built at runtime or be "catch-all" with custom IRouteConstraint.
First of all, lets state some facts and requirements.
We have some data and some metadata about our pages stored in DB;
We don't want to generate a (hypothetically) whole million of routes for all of existing pages beforehand (i.e. on Application startup) because something can change during application and we don't want to tackle with pushing the changes to global RouteCollection;
So we do it this way:
1. PageController
Yes, special controller that is responsible for all our content pages. And there is the only action that is Display(int id) (actually we have a special ViewModel as param but I used an int id for simplicity.
The page with all its data is resolved by ID inside that Display() method. The method itself returns either ViewResult (strongly typed after PageViewModel) or NotFoundResult in case when page is not found.
2. Custom IRouteConstraint
We have to somewhere define if the URL user actually requested refers to one of our custom pages. For this we have a special IsPageConstraint that implements IRouteConstraint interface. In the Match() method of our constraint we just call our PageRepository to check whether there is a page that match our requested URL. We have our PageRepository injected by StructureMap. If we find the page then we add that "id" parameter (with the value) to the RouteData dictionary and it is automatically bound to PageController.Display(int id) by DefaultModelBinder.
But we need a RouteData parameter to check. Where we get that? Here comes...
3. Route mapping with "catch-all" parameter
Important note: this route is defined in the very end of route mappings list because it is very general, not specific. We check all our explicitly defined routes first and then check for a Page (that is easily changeable if needed).
We simply map our route like this:
routes.MapRoute("ContentPages",
"{*pagePath}",
new { controller = "Page", action = "Display" }
new { pagePath = new DependencyRouteConstraint<IsPageConstraint>() });
Stop! What is that DependencyRouteConstraint thing appeared in mapping? Well, thats what does the trick.
4. DependencyRouteConstraint<TConstraint> class
This is just another generic implementation of IRouteConstraint which takes the "real" IRouteConstraint (IsPageConstraint) and resolves it (the given TConstraint) only when Match() method called. It uses dependency injection so our IsPageConstraint instance has all actual dependencies injected!
Our DependencyRouteConstraint then just calls the dependentConstraint.Match() providing all the parameters thus just delegating actual "matching" to the "real" IRouteConstraint.
Note: this class actually has the dependency on ServiceLocator.
Summary
That way we have:
Our Route clear and clean;
The only class that has a dependency on Service Locator is DependencyRouteConstraint;
Any custom IRouteConstraint uses dependency injection whenever needed;
???
PROFIT!
Hope this helps.
So, the problem is:
Route must be defined beforehand, during Application startup
Route's responsibility is to map the incoming URL pattern to the right Controller/Action to perform some task on request. And visa versa - to generate links using that mapping data. Period. Everything else is "Single Responsibility Principle" violation which actually led to your problem.
But UoW dependencies (like NHibernate ISession, or EF ObjectContext) must be resolved at runtime.
And that is why I don't see the children of RouteBase class as a good place for some DB work dependency. It makes everything closely coupled and non-scalable. It is actually impossible to perform Dependency Injection.
From now (I guess there is some kind of already working system) you actually have just one more or less viable option that is:
To use Service Locator pattern: resolve your UoW instance right inside the GetRouteData method (use CommonServiceLocator backed by StructureMap IContainer). That is simple but not really nice thing because this way you get the dependency on static Service Locator itself in your Route.
With CSL you have to just call inside GetRouteData:
var uow = ServiceLocator.Current.GetService<IUnitOfWork>();
or with just StructureMap (without CSL facade):
var uow = ObjectFactory.GetInstance<IUnitOfWork>();
and you're done. Quick and dirty. And the keyword is "dirty" actually :)
Sure, there is much more flexible solution but it needs a few architectural changes. If you provide more details on exactly what data you get in your routes I can try to explain how we solved our Pages routing problem (using DI and custom IRouteConstraint).