Show DeveloperExceptionPage in production but for 'Remote Only" - asp.net-mvc

I understand that the debug error page should not be seen by the end user.
However in the past, I have always been able to configure my production deployment to hide this information (so show a custom or generic error page) when called remotely, but still show the exception/stacktrace debug error, as long as I called it direct from the webserver it was hosted on.
Now looking at the latest MVC/RazorPages way, is it the case this is no longer possible, and it is either on or off, depending on the environment variable?
Before:
Within Web.Config, I use to be able to do something like:
<system.web>
<customErrors mode="RemoteOnly" </customErrors>
Now:
In Startup.cs:
I can see
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
... but I cannot see a way to allow "app.UseDeveloperExceptionPage();" when env.isDevelopement == false, but the call is local.
I am hoping I am missing something, rather than something that has now been removed.

You could possible extend DeveloperExceptionPageMiddleware, or create your own copy, using Url.IsLocalUrl to only display the error view on localhost.

I got it to work (all thanks to others on here). Hopefully it might help others to see the bits I needed, in one place.
First to address identifying if the call is local:
As for:
Url.IsLocalUrl
Supposedly it works, but is 'spoofable'. Given that it could reveal source-code/debug, the guys on this page (In ASP.NET Core how do you check if request is local?) suggest something more like:
public static class HttpContextFilters
{
public static bool IsLocalRequest(HttpContext context)
{
if (context.Connection.RemoteIpAddress.Equals(context.Connection.LocalIpAddress))
{
return true;
}
if (IPAddress.IsLoopback(context.Connection.RemoteIpAddress))
{
return true;
}
return false;
}
public static bool IsRemoteRequest(HttpContext context)
{
return !IsLocalRequest(context);
}
}
I can now call in Statup.cs:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseWhen(HttpContextFilters.IsLocalRequest, configuration => configuration.UseDeveloperExceptionPage());
app.UseWhen(HttpContextFilters.IsRemoteRequest, configuration => configuration.UseExceptionHandler("/Error"));
}
For an alternative solution, I suspect #Jon Galloway's approach would yield a more elegant and expandable solution...
Something along the lines of:
public class MyDeveloperExceptionPageMiddleware : Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware
{
private readonly RequestDelegate _next;
public MyDeveloperExceptionPageMiddleware(RequestDelegate next,
IOptions<DeveloperExceptionPageOptions> options,
ILoggerFactory loggerFactory,
IHostingEnvironment hostingEnvironment,
DiagnosticSource diagnosticSource) : base(next, options, loggerFactory, hostingEnvironment, diagnosticSource)
{
_next = next;
}
public async new Task Invoke(HttpContext httpContext)
{
if (HttpContextFilters.IsLocalRequest(httpContext))
{
//Show dev exceptions page
await base.Invoke(httpContext);
return;
}
await _next(httpContext);
return;
}
public static class MyDeveloperExceptionPageMiddlewareExtensions
{
public static IApplicationBuilder UseMyDeveloperExceptionPageMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<MyDeveloperExceptionPageMiddleware>();
}
}
Then in StartUp.cs do:
app.UseMyDeveloperExceptionPageMiddleware();
For some reason though (due to my ineptness), I couldn't quite get VS to like debugging it, but appeared to work when run from a web server. However, for what I need, and also given the fact that it would need finishing off to handle the custom error page, I think the simplified down and dirty approach above, is enough for me.

Related

Add EvenLogging to an IHost container

I’m creating a console app and have recently started adding custom services to the IHost container so I can simply pass the IHost to any number of factory classes and have everything thing I need to configure them. But I’ve gotten stuck when it comes to adding Windows Event Logging as a service, could use some help getting past this.
My Main static method in Program calls CreateHostBuilder and returns an IHostBuilder as shown below.
public static IHostBuilder CreateHostBuilder(string[] args)
{
IConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddJsonFile("appsettings.json");
IConfiguration configuration = configurationBuilder.Build();
var hostBuilder = Host.CreateDefaultBuilder(args)
.ConfigureLogging((hostContext, logging) =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Information);
logging.AddEventLog(eventViewerSettings =>
{
eventViewerSettings.SourceName = "MeCore2";
eventViewerSettings.LogName = "Application";
eventViewerSettings.MachineName = ".";
});
})
.ConfigureServices(services => services.AddDbContext<MeCore2Context>())
// Add custom service for performing DNS queries
.ConfigureServices(services => services.AddTransient<IDnsQueryService>(DnsQueryFactory.Create))
// Add custom service for Managing Runtime Environment Settings
.ConfigureServices(services => services.AddTransient<IEnvironmentSettings>(EnvironmentSettingsFactory.Create))
// Add custom service for Managing String Extractions
.ConfigureServices(services => services.AddTransient<IExtractStringsService>(ExtraxtStringsFactory.Create))
// Add custom service for IP GeoLocation
.ConfigureServices(services => services.AddTransient<IIpGeolocationService>(IpGeolocationFactory.Create));
return hostBuilder;
}
My factory classes are implemented like this.
public static class DnsQueryFactory
{
public static DnsQueryService Create(IServiceProvider serviceProvider)
{
bool exceptionDisplayOnly = serviceProvider.GetRequiredService<IEnvironmentSettings>().WriteErrorsToEventLogs;
IHost host = serviceProvider.GetRequiredService<IHost>();
return new DnsQueryService(exceptionDisplayOnly, host);
}
}
And my concrete service constructors are implemented like this.
public DnsQueryService(bool exceptionDisplayOnly, IHost host)
{
this.exceptionDisplayOnly = exceptionDisplayOnly;
this.logger = host.Services.GetRequiredService<ILogger>();
this.environmentSettings = host.Services.GetRequiredService<IEnvironmentSettings>();
}
When I ran the app after setting up in this manner, I was unable to pull an ILogger from the host container, I could though, pull an ILoggerFactory then I needed to take some additional steps before I had a fully functional ILogger.
I would like to be able to pull the ILogger from the Host container with it fully configured and ready to use for exception handling, warnings, and basic information logging. But I'm stumped here as I can't seem to get the right syntax for using the ILoggingBuilder or ILoggerFactory into the Host container.
I started down the path of creating a static class EventLoggingServices that would accept an IServiceProvider finish out the configuration steps and return an ILogger, but this too has got me stumped. I'm close but not where I need to be and can't find a blog that covers this approach, either that or I'm going at this the wrong way, to begin with. Appreciate the help and thanks in advance.
I believe I've answered my own question with the following code, it is writing to the event logs. I implemented a factory method to encapsulate the ILogger as follows.
public static class EventLoggingFactory
{
public static ILogger<IEventLogging> Create(IServiceProvider serviceProvider)
{
return new EventLogging().EventLogger;
}
}
public class EventLogging : IEventLogging
{
#region *-- Private Members --*
private ILogger<IEventLogging> _logger = null;
#endregion
public ILogger<IEventLogging> EventLogger { get { return this._logger; } }
public EventLogging()
{
EventLogSettings settings = new EventLogSettings();
settings.LogName = "Application";
settings.SourceName = "MeCore2";
settings.MachineName = ".";
ILoggerFactory loggerFactory = new LoggerFactory();
loggerFactory.AddProvider(new EventLogLoggerProvider(settings));
this._logger = loggerFactory.CreateLogger<IEventLogging>();
}
}
public interface IEventLogging
{
ILogger<IEventLogging> EventLogger { get; }
}
And in my HostBuilder the following:
.ConfigureServices(services => services.AddTransient(EventLoggingFactory.Create))
What I haven't considered and I'm still wrapping my head around are service LifeTimes. Using this approach the Ilogger is Transient, but is that the best way to implement it?
The final code block on this post has been a sufficient solution for my needs. With a little more effort I've been able to expand the features used to capture log data for viewing in Windows Event Viewer.

UWP Template 10 and Service Dendency Injection (MVVM) not WPF

I have spent over two weeks searching google, bing, stack overflow, and msdn docs trying to figure out how to do a proper dependency injection for a mobile app that I am developing. To be clear, I do DI every day in web apps. I do not need a crash course on what, who, and why DI is important. I know it is, and am always embracing it.
What I need to understand is how this works in a mobile app world, and in particular a UWP Template 10 Mobile app.
From my past, in a .net/Asp app I can "RegisterType(new XYZ).Singleton() blah" {please forgive syntax; just an example} in App_Start.ConfigureServices. This works almost identical in .netcore, granted some syntactic changes.
My problem is now I am trying to provide my api is going to an UWP app that needs to digest my IXYZ service. By no means do I think that they should "new" up an instance every time. There has to be a way to inject this into a container on the UWP side; and I feel I am missing something very simple in the process.
Here is the code I have:
App.xaml.cs
public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs args)
{
// TODO: add your long-running task here
//if (args.Kind == ActivationKind.LockScreen)
//{
//}
RegisterServices();
await NavigationService.NavigateAsync(typeof(Views.SearchCompanyPage));
}
public static IServiceProvider Container { get; private set; }
private static void RegisterServices()
{
var services = new ServiceCollection();
services.AddSingleton<IXYZ, XYZ>();
Container = services.BuildServiceProvider();
}
MainPage.xaml.cs:
public MainPage()
{
InitializeComponent();
NavigationCacheMode = NavigationCacheMode.Enabled;
}
MainPageViewModel:
public class MainPageViewModel : ViewModelBase
{
private readonly IXYZ _xyz;
public MainPageViewModel(IXYZ xyz)
{
//Stuff
_xyz= xyz;
}
}
I now get the error:
XAML MainPage...ViewModel type cannot be constructed. In order to be constructed in XAML, a type cannot be abstract, interface nested generic or a struct, and must have a public default constructor.
I am willing to use any brand of IoC Container, but what I need is an example of how to properly use DI for services in a UWP app. 99.9% of questions about DI is about Views (i.e. Prism?) not just a simple DI for a service (i.e. DataRepo; aka API/DataService).
Again, I feel I am missing something obvious and need a nudge in the right direction. Can somebody show me an example project, basic code, or a base flogging on how I should not be a programmer...please don't do that (I don't know if my ego could take it).
You can try to Microsoft.Hosting.Extensions just like ASP.NET, there's an implementation on Xamarin.Forms by James Montemagno, as well it can be used in UWP I have tried and it works perfectly. You have to change some parts in order to get it working.
In OnLaunched Method add Startup.Init();
public static class Startup
{
public static IServiceProvider ServiceProvider { get; set; }
public static void Init()
{
StorageFolder LocalFolder = ApplicationData.Current.LocalFolder;
var configFile = ExtractResource("Sales.Client.appsettings.json", LocalFolder.Path);
var host = new HostBuilder()
.ConfigureHostConfiguration(c =>
{
// Tell the host configuration where to file the file (this is required for Xamarin apps)
c.AddCommandLine(new string[] { $"ContentRoot={LocalFolder.Path}" });
//read in the configuration file!
c.AddJsonFile(configFile);
})
.ConfigureServices((c, x) =>
{
// Configure our local services and access the host configuration
ConfigureServices(c, x);
}).
ConfigureLogging(l => l.AddConsole(o =>
{
//setup a console logger and disable colors since they don't have any colors in VS
o.DisableColors = true;
}))
.Build();
//Save our service provider so we can use it later.
ServiceProvider = host.Services;
}
static void ConfigureServices(HostBuilderContext ctx, IServiceCollection services)
{
//ViewModels
services.AddTransient<HomeViewModel>();
services.AddTransient<MainPageViewModel>();
}
static string ExtractResource(string filename, string location)
{
var a = Assembly.GetExecutingAssembly();
using (var resFilestream = a.GetManifestResourceStream(filename))
{
if (resFilestream != null)
{
var full = Path.Combine(location, filename);
using (var stream = File.Create(full))
{
resFilestream.CopyTo(stream);
}
}
}
return Path.Combine(location, filename);
}
}
Injecting a ViewModel is possible as well which is pretty nice.
With help from #mvermef and the SO question Dependency Injection using Template 10 I found a solutions. This turned out to be a rabbit hole where at every turn I ran into an issue.
The first problem was just getting Dependency Injection to work. Once I was able to get that figured out from the sources above I was able to start injecting my services into ViewModels and setting them to the DataContext in the code behind.
Then I ran into an injection issue problem with injecting my IXYZ services into the ViewModels of UserControls.
Pages and their ViewModels worked great but I had issues with the DataContext of the UserControl not being injected with UserControl's ViewModel. They were instead getting injected by the Page's ViewModel that held it.
The final solution turned out to be making sure that the UserControl had the DataContext being set in XAML not the code behind, as we did with the Pages, and then creating a DependencyProperty in the code behind.
To show the basic solution read below.
To make it work I started with:
APP.XAML.CS
public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs args)
{
// long-running startup tasks go here
RegisterServices();
await Task.CompletedTask;
}
private static void RegisterServices()
{
var services = new ServiceCollection();
services.AddSingleton<IRepository, Repository>();
services.AddSingleton<IBinderService, BinderServices>();
**//ViewModels**
**////User Controls**
services.AddSingleton<AddressesControlViewModel, AddressesControlViewModel>();
services.AddSingleton<CompanyControlViewModel, CompanyControlViewModel>();
**//ViewModels**
**////Pages**
services.AddSingleton<CallListPageViewModel, CallListPageViewModel>();
services.AddSingleton<CallListResultPageViewModel, CallListResultPageViewModel>();
etc....
Container = services.BuildServiceProvider();
}
public override INavigable ResolveForPage(Page page, NavigationService navigationService)
{
**//INJECT THE VIEWMODEL FOR EACH PAGE**
**//ONLY THE PAGE NOT USERCONTROL**
if (page is CallListPage)
{
return Container.GetService<CallListPageViewModel>();
}
if (page is CallListResultPage)
{
return Container.GetService<CallListResultPageViewModel>();
}
etc...
return base.ResolveForPage(page, navigationService);
}
In the code behind for the Page
CALLLISTPAGE.XAML.CS
public CallListPage()
{
InitializeComponent();
}
CallListPageViewModel _viewModel;
public CallListPageViewModel ViewModel
{
get { return _viewModel ?? (_viewModel = (CallListPageViewModel)DataContext); }
}
In your XAML add your UserControl
CALLLISTPAGE.XAML
<binder:CompanyControl Company="{x:Bind ViewModel.SelectedCompany, Mode=TwoWay}"/>
In your UserControl make sure to add the DataContext to the XAML NOT the code behind like we did with the pages.
COMPANYCONTROL.XAML
<UserControl.DataContext>
<viewModels:CompanyControlViewModel x:Name="ViewModel" />
</UserControl.DataContext>
In the UserControl Code Behind add a Dependency Property
COMPANYCONTROL.XAML.CS
public static readonly DependencyProperty CompanyProperty = DependencyProperty.Register(
"Company", typeof(Company), typeof(CompanyControl), new PropertyMetadata(default(Company), SetCompany));
public CompanyControl()
{
InitializeComponent();
}
public Company Company
{
get => (Company) GetValue(CompanyProperty);
set => SetValue(CompanyProperty, value);
}
private static void SetCompany(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as CompanyControl;
var viewModel = control?.ViewModel;
if (viewModel != null)
viewModel.Company = (Company) e.NewValue;
}
In the end I am not sure if this is an elegant solution but it works.

How to add logs in asp.net vNext

I need to set up logs in my asp.net application. It's easy to add output to the console, but I need to configure it in Azure. I don't know how to do it. I need to log all information that occurs with my app into some file and read it.
The ILoggerFactory allows an app to use any implementation of ILogger and ILoggerProvider.
For details on how to implement the interfaces properly, look at the framework's ConsoleLogger and ConsoleLoggerProvider. See also the ASP.NET Core documentation on logging.
Here is a minimal example of a custom ILogger to get started. This is not production code, rather, it demos enough technical depth either to write your own ILogger or to use one from the community.
project.json
"dependencies": {
"Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
"Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
"Microsoft.Extensions.Logging": "1.0.0-rc1-final",
"Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final"
}
MyLoggingProvider.cs
namespace LoggingExample
{
using Microsoft.Extensions.Logging;
public class MyLoggingProvider : ILoggerProvider
{
public ILogger CreateLogger(string categoryName)
{
return new MyLogger();
}
public void Dispose()
{
// TODO Cleanup
}
}
}
MyLogger.cs
In Azure you will want to write to somewhere other than C:/temp/some-guid.txt. This is enough to get you started, though, with writing your own simple logger.
namespace LoggingExample
{
using System;
using Microsoft.Extensions.Logging;
public class MyLogger : ILogger
{
public void Log(LogLevel logLevel, int eventId, object state,
Exception exception, Func<object, Exception, string> formatter)
{
var builder = new StringBuilder();
if (formatter != null) {
builder.AppendLine(formatter(state, exception));
}
var values = state as ILogValues;
if (values != null) {
foreach (var v in values.GetValues()) {
builder.AppendLine(v.Key + ":" + v.Value);
}
}
var logPath = string.Format("C:/temp/{0}.txt", Guid.NewGuid());
File.WriteAllText(logPath, builder.ToString());
}
public bool IsEnabled(LogLevel logLevel) {
return true;
}
public IDisposable BeginScopeImpl(object state) {
return null;
}
}
}
Startup.cs
Now in startup you can use add your logger via loggerFactory.AddProvider(new MyLoggingProvider()). Every call to the ILogger will now log with your provider.
namespace LoggingExample
{
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
using Microsoft.Extensions.Logging;
public class Startup
{
public void Configure(
IApplicationBuilder app,
ILoggerFactory loggerFactory)
{
loggerFactory
.AddConsole(minLevel: LogLevel.Verbose)
.AddProvider(new MyLoggingProvider());
app.Run(async (context) =>
{
var logger = loggerFactory.CreateLogger("CatchAll");
logger.LogInformation("Hello logger!");
await context.Response.WriteAsync("Hello world!");
});
}
}
}
MyController.cs
Anywhere that supports dependency injection can now receive an ILogger that will log to all of the providers that we registered in the Startup.Configure method.
namespace LoggingExample
{
using Microsoft.AspNet.Mvc;
using Microsoft.Extensions.Logging;
public class MyController : Controller
{
public MyController(ILogger logger)
{
logger.LogInformation("Logging from my controller");
}
}
}
Log4Net
Use Log4Net. Its a common framework for logging that everyone who follows up on your code will understand, and it lets you do things like attach a new log "destination" on the fly just by editing your config file. It already covers most of the things you'll want to do (like create a separate file for each "day"), and most of the log mining tools out there will be able to read the files l4n creates.
Setting it Up
There are tutorials online for how to get started, but they basically require a few simple steps:
Download the Log4Net nuget package.
Adjust the log settings in your web.config file
Create a static instance of the logger object
Log Stuff wherever you need to. If you decide you want your logger to write to a file, it will. If you add a database writer, it will write to the db too. Want your log entries to show up in console, just add that logger in your default (debug) config.
Once you get it setup, logging is as simple as this code:
...
} catch(SystemException ex) {
logger.Error("This error was thrown by the XXX routine", ex);
}
Hope that's helpful.
Edit: Config File + Core
As #auga points out in his oh-so-helpful comment, config for ASP.Net 5 may require you to read carefully the link I added under step #2 above (configuring your logger). Instead of re-writing someone else's blog post, I'll just link to the article I used to set this up in our ASP.NET 5 environment. Works really well.
If you're reading this post to learn (instead of skimming it to critique), I'd suggest following the links...

Uncaught exception no application instance

i am working on UI-application that handles multiple entry point approach.
I am referring the link and try for make a demo.
Here is the code :-
public class DemoApp extends UiApplication implements RealtimeClockListener
{
private static DemoApp dmMain ;
private static final long dm_APP_ID = 0x6ef4b845de59ecf9L;
private static DemoApp getDemoApp()
{
if(dmMain == null)
{
RuntimeStore dmAppStore = RuntimeStore.getRuntimeStore();
dmMain = (DemoApp)dmAppStore.get(dm_APP_ID);
}
return dmMain;
}
private static void setDemoApp(DemoApp demoAppMain)
{
RuntimeStore dmAppStore = RuntimeStore.getRuntimeStore();
dmAppStore.remove(dm_APP_ID);
dmAppStore.put(dm_APP_ID, demoAppMain);
}
public static void main(String[] args)
{
Log.d(" Application argument "+args);
if( args.length > 0 && args[ 0 ].equals( "Demo_Alternate" ) )
{
Log.d("Running Demo_Alternate #### Running Demo_Alternate #### Running Demo_Alternate");
dmMain = new DemoApp();
dmMain.enterEventDispatcher();
setDemoApp(dmMain);
}
else
{
Log.d("Running Demo #### Running Demo #### Running Demo #### Running Demo");
getDemoApp().initializeMain();
}
}
public DemoApp()
{
this.addRealtimeClockListener(this);
}
private void initializeMain()
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
try
{
pushScreen(new DemoMainScreen());
} catch (Exception e)
{
Log.e(e.toString());
}
}
});
}
public void clockUpdated()
{
showMessage("DemoAppClock Updated");
Log.d("DemoAppClock Updated #### DemoAppClock Updated #### DemoAppClock Updated");
}
private void showMessage(String message)
{
synchronized (Application.getEventLock())
{
Dialog dlg = new Dialog(Dialog.D_OK, message, Dialog.OK, null, Manager.FIELD_HCENTER);
Ui.getUiEngine().pushGlobalScreen(dlg, 1, UiEngine.GLOBAL_QUEUE);
}
}
}
:- I have created an alternate entry point named Demo_Alternate , that runs at start up.
:- If the application has separate entry points, that means a separate process the link
Now my questions are :-
While running the code, I am getting "Uncaught exception : no application instance".
I just want to make one application instance - don't want separate processes.
Can we use (Application) Singleton approach for alternate entry-points?
Only looked briefly at this code, but see an obvious problem here:
dmMain.enterEventDispatcher();
setDemoApp(dmMain);
enterEventDispatcher never returns, so you never put your Application instance in RuntimeStore.
I suggest you review the following KB article, you might find its approach to accessing a RuntimeStore maintained object easier to use. Or not.
Singleton using RuntimeStore
Update
If this solution does not work, please update your original post with the corrected code.
I certainly agree with Peter, that calling setDemoApp(dmMain) after enterEventDispatcher() means it doesn't get called.
That said, I think you have a more basic misunderstanding here.
Using alternate entry points will create multiple processes. See here for more.
But, you say that you don't want separate processes. Can you tell us why not?
Separate BlackBerry processes that are designed to work together can still share data, using the RuntimeStore, for example.
Maybe you could tell us more about what your "Demo" and "Demo Alternate" are supposed to do.

Why is a VerifyError thrown when publishing changes with a decorated HtmlResponseWriter

I am facing a problem when publishing changes to WebSphere with JSF2 (Myfaces 2.0.12).
Everytime I publish a change to my local server (WebSphere) I am getting a java.lang.VerifyError. After a full restart of the server the application runs smoothly with my changes.
java.lang.VerifyError: com/sun/faces/renderkit/html_basic/HtmlResponseWriter.startElement(Ljava/lang/String;Ljavax/faces/component/UIComponent;)V
The StackTrace indicates that something is wrong with the ResponseWriter and indeed we changed a little bit there ;-)
For accessibility-reasons I have to have full controll of the HTML so I need custom HtmlRenderers. To reduce duplicate code I decorated the ResponseWriter I get from the FacesContext with my own, and provide additional convenience-methods on top.
public class CustomResponseWriter<T extends UIInput & MyFormdataInterface> extends HtmlResponseWriter
{
public CustomResponseWriter(ReponseWriter writer){
super(writer, writer.getContentType(), writer.getCharacterEncoding());
}
public writeFancy(T component)
{
...
writeText(component.getMyFanceAttribute(), null);
...
}
}
As I said, the code runs fine after the server was restarted so I assume the code is correct. But on the other side, this error occurs only on pages where I use this CustomReponseWriter.
Is there anything wrong with the idea of decorating the ResponseWriter in a new class? Or might this just be a problem in WebSphere?
As lu4242 mentioned in his comment, I changed the implementation from decorator to a delegate and the problem disappeared. It would be nice to understand why this happens but for now here is the changed code (I dont like the verbose code from the delegate in this case but as long as it works).
public class CustomResponseWriter<T extends UIInput & MyFormdataInterface> extends ResponseWriter
{
private ResponseWriter delegateWriter;
public CustomResponseWriter(ReponseWriter writer){
this.delegateWriter = writer;
}
public writeFancy(T component)
{
...
writeText(component.getMyFanceAttribute(), null);
...
}
public String getContentType()
{
this.delegateWriter.getContentType();
}
//... and so on for all methods from ResponseWriter...
}
}

Resources