问:
How sets avoid duplicates internally?
I had a doubt about the set in Collections framework. How the set itself will identify duplicates and how it will come to know? Could anyone please explain how it is implemented? How hashcode and equals method will come into the picture? I need a brief explanation as it is really important for me.</p>

答:
"Can u please explain with these example. s.add("123");s.add("123");"

For the above query explained in context with Set interface,  Please refer to the below snippet and explanation.

```<code>public void setTest() {
    Set<String> obj = new HashSet<>();
    System.out.println(obj.add("123")); //Output : true
    System.out.println(obj.add("123")); //Output : false
}
</code>```

If you notice in the above snippet, we have added 123 two times.  for the first time add SOP will return true.  then for the second time of added "123", SOP will return false.

With this we can understand that, if we add same value in the Set for the second time or more, then the duplicated value will be skipped.

Title: How sets avoid duplicates internally?

Body:
"Can u please explain with these example. s.add("123");s.add("123");"

For the above query explained in context with Set interface,  Please refer to the below snippet and explanation.

public void setTest() {
    Set<String> obj = new HashSet<>();
    System.out.println(obj.add("123")); //Output : true
    System.out.println(obj.add("123")); //Output : false
}

If you notice in the above snippet, we have added 123 two times.  for the first time add SOP will return true.  then for the second time of added "123", SOP will return false.

With this we can understand that, if we add same value in the Set for the second time or more, then the duplicated value will be skipped.


来源: stackexchange

问:
Why won't this CSV print out correctly? (Magento Categories)
I have a script that is meant to output Magento categories' data to a CSV file:

<?php

require_once 'app/Mage.php';
Mage::app();
$categoryId = 228;
$category = Mage::getModel('catalog/category')->load($categoryId);

$outputFile = "var/export/categories-and-ids.csv";
$write = fopen($outputFile, 'w');

echo '```';

function writeoutcategory($parent)
{
  $_categories = $parent->getChildrenCategories();
  foreach($_categories as $cat)
  {
    $data = [/*
      '"'.trim($cat->getName()).'"',
      '"'.$cat->getId().'"',
      '"'.trim($cat->getParentCategory()->getName()).'"',
      '"'.$cat->getParentCategory()->getId().'"',*/
      trim($cat->getName()),
      $cat->getId(),
      trim($cat->getParentCategory()->getName()),
      $cat->getParentCategory()->getId(),
    ];
    print_r($data); echo '<br>';
    fputcsv($write, $data);

    if(count($cat->getChildrenCategories())) writeoutcategory($cat);
  }
}

writeoutcategory($category);

echo '```';

fclose($write);

echo "File written at ".$outputFile;```
</div>
</div>
</p>
<p>Before and I don't know why then and not now it was printing fine, just every row was all in one column separated by commas.</p>
<p>Now it comes out just a bunch of jarbled symbols (in OpenOffice Calc). When "Filter Selection" comes up prior to opening the file, I choose Text CSV, then UTF-8 encoding, then it opens this up in OpenOffice Writer (?):</p>
<blockquote>
<p>��#ࡱ#�################;###��  #############################����####����########�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������R#o#o#t#</p>
<h1>E#n#t#r#y#################################################������������####################################����############################################################################������������####################################����############################################################################������������####################################����############################################################################������������####################################����</h1>
</blockquote>
<p>What am I doing wrong, please?</p>
<p>This makes no sense. Updated the file to:</p>
```header('Content-Type: text/html; charset=utf-8');

require_once 'app/Mage.php';
Mage::app();
$categoryId = 228; // PTL > Tablecloths
$category = Mage::getModel('catalog/category')->load($categoryId);

echo '```';

$rows = [];

function collectCategories($parent)
{
  $_categories = $parent->getChildrenCategories();
  foreach($_categories as $cat)
  {
    $data = [
      trim($cat->getName()),
      $cat->getId(),
      trim($cat->getParentCategory()->getName()),
      $cat->getParentCategory()->getId(),
    ];
    var_dump($data);
    $rows[] = $data;

    if(count($cat->getChildrenCategories())) collectCategories($cat);
  }
}

collectCategories($category);

echo '```';

$outputFile = "var/export/categories-and-ids.csv";
$write = fopen($outputFile, 'w');
foreach($rows as $row) fputcsv($write, $row);
fclose($write);
echo "File written at ".$outputFile;
```
<p>It still opens the above in OO Calc and blank in Notepad. What could possibly be wrong?</p>
<p>UPDATE: Now I've simply appended the file with this:</p>
```$list = array (
    array('aaa', 'bbb', 'ccc', 'dddd'),
    array('123', '456', '789'),
    array('"aaa"', '"bbb"')
);

$fp = fopen('var/export/file.csv', 'w');

foreach ($list as $fields) {
    fputcsv($fp, $fields);
}

fclose($fp);
```
<p>Which outputs this (Atom):</p>
```aaa,bbb,ccc,dddd
123,456,789
"""aaa""","""bbb"""
```
<p>This in OO Calc:</p>
```aaa,bbb,ccc,dddd
123456789
"aaa","""bbb"""
```

(one column)

and my categories-and-ids.csv is still blank and won't open as CSV through OO.

答: OH wow the function wasn't returning anything obviously it wasn't adding to $rows as $rows was initialized outside of it. I'm an idiot.</p>

ContentLicense: CC BY-SA 3.0

Body:
I have a script that is meant to output Magento categories' data to a CSV file:

<?php

require_once 'app/Mage.php';
Mage::app();
$categoryId = 228;
$category = Mage::getModel('catalog/category')->load($categoryId);

$outputFile = "var/export/categories-and-ids.csv";
$write = fopen($outputFile, 'w');

echo '
';

function writeoutcategory($parent)
{
  $_categories = $parent->getChildrenCategories();
  foreach($_categories as $cat)
  {
    $data = [/*
      '"'.trim($cat->getName()).'"',
      '"'.$cat->getId().'"',
      '"'.trim($cat->getParentCategory()->getName()).'"',
      '"'.$cat->getParentCategory()->getId().'"',*/
      trim($cat->getName()),
      $cat->getId(),
      trim($cat->getParentCategory()->getName()),
      $cat->getParentCategory()->getId(),
    ];
    print_r($data); echo '
';
    fputcsv($write, $data);

    if(count($cat->getChildrenCategories())) writeoutcategory($cat);
  }
}

writeoutcategory($category);

echo '
';

fclose($write);

echo "File written at ".$outputFile;

Before and I don't know why then and not now it was printing fine, just every row was all in one column separated by commas.

Now it comes out just a bunch of jarbled symbols (in OpenOffice Calc). When "Filter Selection" comes up prior to opening the file, I choose Text CSV, then UTF-8 encoding, then it opens this up in OpenOffice Writer (?):

��#ࡱ#�################;###��  #############################����####����########�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������R#o#o#t#

E#n#t#r#y#################################################������������####################################����############################################################################������������####################################����############################################################################������������####################################����############################################################################������������####################################����

What am I doing wrong, please?

This makes no sense. Updated the file to:

header('Content-Type: text/html; charset=utf-8');

require_once 'app/Mage.php';
Mage::app();
$categoryId = 228; // PTL > Tablecloths
$category = Mage::getModel('catalog/category')->load($categoryId);

echo '
';

$rows = [];

function collectCategories($parent)
{
  $_categories = $parent->getChildrenCategories();
  foreach($_categories as $cat)
  {
    $data = [
      trim($cat->getName()),
      $cat->getId(),
      trim($cat->getParentCategory()->getName()),
      $cat->getParentCategory()->getId(),
    ];
    var_dump($data);
    $rows[] = $data;

    if(count($cat->getChildrenCategories())) collectCategories($cat);
  }
}

collectCategories($category);

echo '
';

$outputFile = "var/export/categories-and-ids.csv";
$write = fopen($outputFile, 'w');
foreach($rows as $row) fputcsv($write, $row);
fclose($write);
echo "File written at ".$outputFile;

It still opens the above in OO Calc and blank in Notepad. What could possibly be wrong?

UPDATE: Now I've simply appended the file with this:

$list = array (
    array('aaa', 'bbb', 'ccc', 'dddd'),
    array('123', '456', '789'),
    array('"aaa"', '"bbb"')
);

$fp = fopen('var/export/file.csv', 'w');

foreach ($list as $fields) {
    fputcsv($fp, $fields);
}

fclose($fp);

Which outputs this (Atom):

aaa,bbb,ccc,dddd
123,456,789
"""aaa""","""bbb"""

This in OO Calc:

aaa,bbb,ccc,dddd
123456789
"aaa","""bbb"""

(one column)

and my categories-and-ids.csv is still blank and won't open as CSV through OO.


问:
Vue2 custom event with native dom element
I have just started learning vue2. While playing with components and custom-event, i am facing a problem. I am expecting an alert with text caught but nothing happens. Below is the simple code:

```<code><div class="container" id="app" >
    <div v-on:newmessage="handleNewMessage">
        <message></message>
    </div>
</div>

<script>

    Vue.component('message',{
        template: '<input type="text" @keyup.enter="handleInput">',
        methods: {
            handleInput: function(event)
            {
                this.$emit('newmessage');
            },
        }
    });

    var demo = new Vue({
        el: '#app',

        methods: {
            handleNewMessage: function(message)
            {
                alert('caught');
            }
        },
    });

</script>
</code>```

Please note that if i move the newmessage event listener from the div element to the message element, this works fine and the alert is generated:

```<code> //this works
 <div >
     <message v-on:newmessage="handleNewMessage"></message>
</div>
</code>```

I might as well be missing something very basic here. Do custom events not propagate up to native dom parent elements? I spent whole evening searching for a reference but no luck.

Thanks in advance.

答:
Yes, it works as you explained since $emit is only visible at <message> tag (as I know it) and NOT at the
 enclosing it. You can try directly emitting to the root component (#app) and wire the handler there too.

```<code>this.$root.$emit('newmessage')
</code>```

and,

```<code><div class="container" id="app" v-on:newmessage="handleNewMessage">
</code>```

(EDIT)and,

```<code>const component = Vue.component('message' ...)

new Vue({
    el: '#app',
    components: component
    ...)
</code>```

Basically, you are not doing anything wrong here.

PS: I haven't run EDIT. But, the idea is along those lines. Let me know if that works.

Body:
I have just started learning vue2. While playing with components and custom-event, i am facing a problem. I am expecting an alert with text caught but nothing happens. Below is the simple code:

        <message></message>

Please note that if i move the newmessage event listener from the div element to the message element, this works fine and the alert is generated:

 //this works

     <message v-on:newmessage="handleNewMessage"></message>

I might as well be missing something very basic here. Do custom events not propagate up to native dom parent elements? I spent whole evening searching for a reference but no luck.

Thanks in advance.

Body:
Yes, it works as you explained since $emit is only visible at <message> tag (as I know it) and NOT at the <div> enclosing it. You can try directly emitting to the root component (#app) and wire the handler there too.

this.$root.$emit('newmessage')

and,

<div class="container" id="app" v-on:newmessage="handleNewMessage">

(EDIT)and,

const component = Vue.component('message' ...)

new Vue({
    el: '#app',
    components: component
    ...)

Basically, you are not doing anything wrong here.

PS: I haven't run EDIT. But, the idea is along those lines. Let me know if that works.


问:
Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(CharacterList)
I am trying to test my React "supersquadapp" and getting the following error.

Uncaught Error: Could not find "store" in either the context or props of "Connect(CharacterList)". Either wrap the root component in a , or explicitly pass "store" as a prop to "Connect(CharacterList)".

characterlist.js

```<code>import React, { Component } from 'react';
import { connect } from 'react-redux';

class CharacterList extends Component {
    render() {
        console.log('this.props', this.props);
        return (
            <div>
                <h4>characters</h4>
            </div>
        )
    }

}
function mapStateToProps(state) {
    return {
        characters: state.characters
    }
}

export default connect(mapStateToProps, null)(CharacterList);
</code>```

app.js

```<code>import React, {Component} from 'react';
import CharacterList from './CharacterList';

class App extends Component {
    render() {
        return (
            <div>
                <h2>SUPER SQUAD</h2>
                <CharacterList />
            </div>
        )
    }
}
export default App;
</code>```

index.js

```<code>import React from 'react';
import ReactDOM from 'react-dom';
import App from './Components/App';

import { createStore } from 'redux';
import { Provider } from 'react-redux';

import rootReducers from './reducers';
import { addCharacterById } from './actions';

const store = createStore(rootReducers);
console.log(store.getState());
store.subscribe(() => console.log('store',store.getState()))
store.dispatch(addCharacterById(3));

ReactDOM.render(
    <Provider>
        <App />
     </Provider>
    ,document.getElementById('root')
)
</code>```

character.js(in reducers folder)

```<code>import characters_json from '../Data/characters.json';
import { ADD_CHARACTER } from '../actions';

function characters(state = characters_json, action) {
    switch(action.type) {
        case ADD_CHARACTER:
        let characters = state.filter(item => item.id !== action.id);
        return characters;
        default:
            return state;
    }
}
export default characters;
</code>```

heroes.js(reducers folder)

```<code>import { ADD_CHARACTER } from '../actions';
import {createCharacter} from './helper';

function heroes(state = [], action) {
    switch(action.type) {
        case ADD_CHARACTER:
        let heroes = [...state, createCharacter(action.id)];
        return heroes;
        default:
        return state;
    }
}
export default heroes;
</code>```

helper.js(reducers folder)

```<code>import characters_json from '../Data/characters.json';

export function createCharacter(id) {
    let character = characters_json.find(c => c.id === id);
    return character;
}
</code>```

index.js(reducers folder)

```<code>import { combineReducers } from 'redux';
import characters from './characters_reducer';
import heroes from './heroes_reducer';

const rootReducer = combineReducers({
    characters,
    heroes
})
export default rootReducer;
</code>```

index.js(action folder)

```<code>export const ADD_CHARACTER = 'ADD_CHARACTER';

export function addCharacterById(id) {
    const action = {
        type:ADD_CHARACTER,
        id
    }
    return action;
}
</code>```

The above error occurred in the  component:

in Connect(CharacterList) (at App.js:9)

in div (at App.js:7)

in App (at index.js:19)

in Provider (at index.js:18)

please help me...?

答:
If you are running a test and you have something like alechill's answer, you'd need this to change in the test, for example:</p>

```<code>let mockedStore = configureStore([])({});
test('some test', () => {
  const wrapper = mount(<SomeComponent foo="bar" />, {
    context: { store: mockedStore },
    childContextTypes: { store: PropTypes.object.isRequired }
  });
  expect(.... your tests here);
});
</code>```

Body:
I am trying to test my React "supersquadapp" and getting the following error.

Uncaught Error: Could not find "store" in either the context or props of "Connect(CharacterList)". Either wrap the root component in a , or explicitly pass "store" as a prop to "Connect(CharacterList)".

characterlist.js

import React, { Component } from 'react';
import { connect } from 'react-redux';

class CharacterList extends Component {
    render() {
        console.log('this.props', this.props);
        return (

characters

        )
    }

}
function mapStateToProps(state) {
    return {
        characters: state.characters
    }
}

export default connect(mapStateToProps, null)(CharacterList);

app.js

import React, {Component} from 'react';
import CharacterList from './CharacterList';

class App extends Component {
    render() {
        return (

SUPER SQUAD

                <CharacterList />

        )
    }
}
export default App;

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './Components/App';

import { createStore } from 'redux';
import { Provider } from 'react-redux';

import rootReducers from './reducers';
import { addCharacterById } from './actions';

const store = createStore(rootReducers);
console.log(store.getState());
store.subscribe(() => console.log('store',store.getState()))
store.dispatch(addCharacterById(3));

ReactDOM.render(
    <Provider>
        <App />
     </Provider>
    ,document.getElementById('root')
)

character.js(in reducers folder)

import characters_json from '../Data/characters.json';
import { ADD_CHARACTER } from '../actions';

function characters(state = characters_json, action) {
    switch(action.type) {
        case ADD_CHARACTER:
        let characters = state.filter(item => item.id !== action.id);
        return characters;
        default:
            return state;
    }
}
export default characters;

heroes.js(reducers folder)

import { ADD_CHARACTER } from '../actions';
import {createCharacter} from './helper';

function heroes(state = [], action) {
    switch(action.type) {
        case ADD_CHARACTER:
        let heroes = [...state, createCharacter(action.id)];
        return heroes;
        default:
        return state;
    }
}
export default heroes;

helper.js(reducers folder)

import characters_json from '../Data/characters.json';

export function createCharacter(id) {
    let character = characters_json.find(c => c.id === id);
    return character;
}

index.js(reducers folder)

import { combineReducers } from 'redux';
import characters from './characters_reducer';
import heroes from './heroes_reducer';

const rootReducer = combineReducers({
    characters,
    heroes
})
export default rootReducer;

index.js(action folder)

export const ADD_CHARACTER = 'ADD_CHARACTER';

export function addCharacterById(id) {
    const action = {
        type:ADD_CHARACTER,
        id
    }
    return action;
}

The above error occurred in the  component:

in Connect(CharacterList) (at App.js:9)

in div (at App.js:7)

in App (at index.js:19)

in Provider (at index.js:18)

please help me...?

Body:
If you are running a test and you have something like alechill's answer, you'd need this to change in the test, for example:

let mockedStore = configureStore([])({});
test('some test', () => {
  const wrapper = mount(<SomeComponent foo="bar" />, {
    context: { store: mockedStore },
    childContextTypes: { store: PropTypes.object.isRequired }
  });
  expect(.... your tests here);
});


问:
How do I use RxJS to process hundreds of requests without crashing?

I need to process 400+ employee objects which involves calling an observable service method for each one.

I need to know when all employees have been processed, and, I need to find a way of doing this which does not cause my client or server to be overloaded with simultaneous requests - that's what's happening at the moment.

I want to gather the results of each employee's processing into to an array from which I can further work with the data (I'm creating an export file).

I have been trying RxJS concat and forkjoin but I still seem to have 400+ tasks all firing off at the same time.

I read this page about concat which suggests that the processing is handled one-at-a-time, (like a queue at an ATM) but I'm not convinced - again my browser hung and the number of network requests suggested all-at-the-same-time to me.

If I could get the code to process one employee at a time and finish before handling the next employee in the list, that would be just fine.

```<code>processEmployees(): AsyncSubject<boolean> {
    let employeesProcessed: AsyncSubject<boolean> = new AsyncSubject<boolean>();
    let listOfProcessesToRun = [];

    this.employeeProfilesList.forEach(
        (employeeProfile: EmployeeProfile) => {
            listOfProcessesToRun.push(
                this.annualLeaveCalculationService.startProcess(employeeProfile, this.yearToProcess).delay(2000)
            );
        }
    )

    Observable.concat(listOfProcessesToRun)
        .finally(() => {
        })
        .subscribe(
        (calculationResults: AnnualLeaveCalculationResults) => {
            this.calculationResults.push(calculationResults);
            employeesProcessed.complete();
        },
        error => {
        });

    return employeesProcessed;
}
</code>```

I have tried using Observable.forkjoin to process an array of observables, but I believe that the requests are handled in parallel, and that resulted in my machine hanging due to there being some 400 employees to process.

I have considered a nested solution, e.g.

```<code>processemployee(X) {
    doServiceCall(this.employees[x])
    .subscribe( response => {
            processemployee(++x); // with a check to detect number of loops
        }
    );
}
</code>```

but I'm not sure that's a great pattern.

答: You can use the .mergeMap overload which takes the concurreny and set it to something sane (like 20req concurrent) to your service. That way you optimise for maximum throughput without swamping your server.

Body:
I need to process 400+ employee objects which involves calling an observable service method for each one.

I need to know when all employees have been processed, and, I need to find a way of doing this which does not cause my client or server to be overloaded with simultaneous requests - that's what's happening at the moment.

I want to gather the results of each employee's processing into to an array from which I can further work with the data (I'm creating an export file).

I have been trying RxJS concat and forkjoin but I still seem to have 400+ tasks all firing off at the same time.

I read this page about concat which suggests that the processing is handled one-at-a-time, (like a queue at an ATM) but I'm not convinced - again my browser hung and the number of network requests suggested all-at-the-same-time to me.

If I could get the code to process one employee at a time and finish before handling the next employee in the list, that would be just fine.

processEmployees(): AsyncSubject<boolean> {
    let employeesProcessed: AsyncSubject<boolean> = new AsyncSubject<boolean>();
    let listOfProcessesToRun = [];

    this.employeeProfilesList.forEach(
        (employeeProfile: EmployeeProfile) => {
            listOfProcessesToRun.push(
                this.annualLeaveCalculationService.startProcess(employeeProfile, this.yearToProcess).delay(2000)
            );
        }
    )

    Observable.concat(listOfProcessesToRun)
        .finally(() => {
        })
        .subscribe(
        (calculationResults: AnnualLeaveCalculationResults) => {
            this.calculationResults.push(calculationResults);
            employeesProcessed.complete();
        },
        error => {
        });

    return employeesProcessed;
}

I have tried using Observable.forkjoin to process an array of observables, but I believe that the requests are handled in parallel, and that resulted in my machine hanging due to there being some 400 employees to process.

I have considered a nested solution, e.g.

processemployee(X) {
    doServiceCall(this.employees[x])
    .subscribe( response => {
            processemployee(++x); // with a check to detect number of loops
        }
    );
}

but I'm not sure that's a great pattern.


问:
WebSphere Contextlistener not authenticated
We have as application which where ported from WAS 5 to WAS 8. After some changes I found that context listener is not executed as authenticated user.

We have following web-app definition:

```<code><?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <display-name>InDiaServerMonitoring</display-name>
    <listener>
        <description>
        </description>
        <display-name>
        Timer Control Listener</display-name>
        <listener-class>servlet.TimerControlListener</listener-class>
    </listener>
    <servlet>
        <display-name>
        MonitoringServlet</display-name>
        <servlet-name>MonitoringServlet</servlet-name>
        <servlet-class>servlet.MonitoringServlet</servlet-class>
        <run-as>
            <role-name>monitor</role-name>
        </run-as>
    </servlet>
    <servlet-mapping>
        <servlet-name>MonitoringServlet</servlet-name>
        <url-pattern>/MonitoringServlet</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    <security-role>
        <role-name>monitor</role-name>
    </security-role>
    <ejb-local-ref id="EJBLocalRef_1213267259466">
        <description>
        </description>
        <ejb-ref-name>ejb/Service</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <local-home>business.ServiceControllerLocalHome</local-home>
        <local>business.ServiceControllerLocal</local>
        <ejb-link>Services.jar#ServiceController</ejb-link>
    </ejb-local-ref>
</web-app>
</code>```

We would like to execute custom code on ServiceController which require user (any user) to be authenticated. We have deffined user for monitoring page to be used. Actually monitoring page is accessible without user authentication, but inside listener we are getting not authorised exception like:

```<code>javax.ejb.AccessLocalException:  ; nested exception is: com.ibm.websphere.csi.CSIAccessException: SECJ0053E: Authorization failed for None/server:iap_iapnode0_server while invoking (Bean)Prj#EJB.jar#ServiceController stopTimers::3  is not granted any of the required roles: user
at com.ibm.ws.security.core.SecurityCollaborator.performAuthorization(SecurityCollaborator.java:626)
at com.ibm.ws.security.core.EJSSecurityCollaborator.preInvoke(EJSSecurityCollaborator.java:265)
at com.ibm.ejs.container.EJSContainer.preInvokeAfterActivate(EJSContainer.java:4214)
at com.ibm.ejs.container.EJSContainer.EjbPreInvoke(EJSContainer.java:3481)
at business.EJSLocalCSLServiceController_f7e0e567.stopTimers(EJSLocalCSLItrServiceController_f7e0e567.java)
at monitoring.servlet.TimerControlListener.contextInitialized(TimerControlListener.java:70)
at com.ibm.ws.webcontainer.webapp.WebApp.notifyServletContextCreated(WebApp.java:1686)
at com.ibm.ws.webcontainer.webapp.WebAppImpl.initialize(WebAppImpl.java:410)
at com.ibm.ws.webcontainer.webapp.WebGroupImpl.addWebApplication(WebGroupImpl.java:88)
at com.ibm.ws.webcontainer.VirtualHostImpl.addWebApplication(VirtualHostImpl.java:169)
at com.ibm.ws.webcontainer.WSWebContainer.addWebApp(WSWebContainer.java:749)
at com.ibm.ws.webcontainer.WSWebContainer.addWebApplication(WSWebContainer.java:634)
at com.ibm.ws.webcontainer.component.WebContainerImpl.install(WebContainerImpl.java:422)
at com.ibm.ws.webcontainer.component.WebContainerImpl.start(WebContainerImpl.java:714)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:1164)
at com.ibm.ws.runtime.component.DeployedApplicationImpl.fireDeployedObjectStart(DeployedApplicationImpl.java:1369)
at com.ibm.ws.runtime.component.DeployedModuleImpl.start(DeployedModuleImpl.java:639)
at com.ibm.ws.runtime.component.DeployedApplicationImpl.start(DeployedApplicationImpl.java:967)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplication(ApplicationMgrImpl.java:770)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplicationDynamically(ApplicationMgrImpl.java:1361)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:2162)
at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:446)
at com.ibm.ws.runtime.component.CompositionUnitImpl.start(CompositionUnitImpl.java:123)
at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:389)
at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.access$500(CompositionUnitMgrImpl.java:117)
at com.ibm.ws.runtime.component.CompositionUnitMgrImpl$1.run(CompositionUnitMgrImpl.java:664)
at com.ibm.ws.security.auth.ContextManagerImpl.runAs(ContextManagerImpl.java:5468)
at com.ibm.ws.security.auth.ContextManagerImpl.runAsSystem(ContextManagerImpl.java:5594)
at com.ibm.ws.security.core.SecurityContext.runAsSystem(SecurityContext.java:255)
at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.startCompositionUnit(CompositionUnitMgrImpl.java:678)
at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.startCompositionUnit(CompositionUnitMgrImpl.java:622)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplication(ApplicationMgrImpl.java:1251)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:69)
at sun.reflect.GeneratedMethodAccessor54.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:272)
at javax.management.modelmbean.RequiredModelMBean$4.run(RequiredModelMBean.java:1152)
at java.security.AccessController.doPrivileged(AccessController.java:298)
at com.ibm.oti.security.CheckedAccessControlContext.securityCheck(CheckedAccessControlContext.java:30)
at sun.misc.JavaSecurityAccessWrapper.doIntersectionPrivilege(JavaSecurityAccessWrapper.java:41)
at javax.management.modelmbean.RequiredModelMBean.invokeMethod(RequiredModelMBean.java:1146)
at javax.management.modelmbean.RequiredModelMBean.invoke(RequiredModelMBean.java:999)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:847)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:783)
at com.ibm.ws.management.AdminServiceImpl$1.run(AdminServiceImpl.java:1335)
at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:118)
at com.ibm.ws.management.AdminServiceImpl.invoke(AdminServiceImpl.java:1228)
at com.ibm.ws.management.commands.AdminServiceCommands$InvokeCmd.execute(AdminServiceCommands.java:251)
at com.ibm.ws.console.core.mbean.MBeanHelper.invoke(MBeanHelper.java:241)
at com.ibm.ws.console.appdeployment.ApplicationDeploymentCollectionAction.execute(ApplicationDeploymentCollectionAction.java:578)
at org.apache.struts.action.RequestProcessor.processActionPerform(Unknown Source)
at org.apache.struts.action.RequestProcessor.process(Unknown Source)
at org.apache.struts.action.ActionServlet.process(Unknown Source)
at org.apache.struts.action.ActionServlet.doPost(Unknown Source)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:595)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1230)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:779)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:478)
at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:178)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.invokeTarget(WebAppFilterChain.java:136)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:79)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:960)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1064)
at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.dispatch(WebAppRequestDispatcher.java:1385)
at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java:194)
at org.apache.struts.action.RequestProcessor.doForward(Unknown Source)
at org.apache.struts.tiles.TilesRequestProcessor.doForward(Unknown Source)
at org.apache.struts.action.RequestProcessor.processForwardConfig(Unknown Source)
at org.apache.struts.tiles.TilesRequestProcessor.processForwardConfig(Unknown Source)
at org.apache.struts.action.RequestProcessor.process(Unknown Source)
at org.apache.struts.action.ActionServlet.process(Unknown Source)
at org.apache.struts.action.ActionServlet.doPost(Unknown Source)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:595)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1230)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:779)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:478)
at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:178)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.invokeTarget(WebAppFilterChain.java:136)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:97)
at com.ibm.ws.console.core.servlet.WSCUrlFilter.setUpCommandAssistance(WSCUrlFilter.java:955)
at com.ibm.ws.console.core.servlet.WSCUrlFilter.continueStoringTaskState(WSCUrlFilter.java:504)
at com.ibm.ws.console.core.servlet.WSCUrlFilter.doFilter(WSCUrlFilter.java:325)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:195)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:91)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:960)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1064)
at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:87)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:914)
at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1662)
at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:200)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:453)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:515)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:306)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java:277)
at com.ibm.ws.ssl.channel.impl.SSLConnectionLink.determineNextChannel(SSLConnectionLink.java:1049)
at com.ibm.ws.ssl.channel.impl.SSLConnectionLink$MyReadCompletedCallback.complete(SSLConnectionLink.java:643)
at com.ibm.ws.ssl.channel.impl.SSLReadServiceContext$SSLReadCompletedCallback.complete(SSLReadServiceContext.java:1819)
at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:175)
at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)
at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138)
at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204)
at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775)
at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:905)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1702)
Caused by: com.ibm.websphere.csi.CSIAccessException: SECJ0053E: Authorization failed for None/server:iap_iapnode0_xd while invoking (Bean)InDiaPrj#InDiaTBItrEJB.jar#ItrServiceController stopTimers::3  is not granted any of the required roles: user
... 112 more
</code>```

答:
Context listener cannot have any run as role associated with it.
You are trying to invoke  (Bean)Prj#EJB.jar#ServiceController stopTimers from that context listener, which looks like is secured and requires user which is not accessible by anonymous users.

So you have following solutions:

1) Use programmatic login in your context, with similar code to this:

```<code>// create login context
LoginContext lc = new LoginContext( "WSLogin", new WSCallbackHandlerImpl(userid, password));
// do login
lc.login();
// retrieve subject
Subject subject = lc.getSubject();
// set new identity
WSSubject.setRunAsSubject(subject);
// call session bean
itrServiceController.stopTimers();
// logout - destroy credentials
lc.logout();
</code>```

2) Use intermediate servlet or EJB with runas role set.

So from your listener you just call servlet or local session bean, which will have runAs role set, and that bean will simply call your ItrServiceController using associated with role user.

This is probably easier as it allows to define that user/role mapping on deployment.

Body:
We have as application which where ported from WAS 5 to WAS 8. After some changes I found that context listener is not executed as authenticated user.

We have following web-app definition:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <display-name>InDiaServerMonitoring</display-name>
    <listener>
        <description>
        </description>
        <display-name>
        Timer Control Listener</display-name>
        <listener-class>servlet.TimerControlListener</listener-class>
    </listener>
    <servlet>
        <display-name>
        MonitoringServlet</display-name>
        <servlet-name>MonitoringServlet</servlet-name>
        <servlet-class>servlet.MonitoringServlet</servlet-class>
        <run-as>
            <role-name>monitor</role-name>
        </run-as>
    </servlet>
    <servlet-mapping>
        <servlet-name>MonitoringServlet</servlet-name>
        <url-pattern>/MonitoringServlet</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    <security-role>
        <role-name>monitor</role-name>
    </security-role>
    <ejb-local-ref id="EJBLocalRef_1213267259466">
        <description>
        </description>
        <ejb-ref-name>ejb/Service</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <local-home>business.ServiceControllerLocalHome</local-home>
        <local>business.ServiceControllerLocal</local>
        <ejb-link>Services.jar#ServiceController</ejb-link>
    </ejb-local-ref>
</web-app>

We would like to execute custom code on ServiceController which require user (any user) to be authenticated. We have deffined user for monitoring page to be used. Actually monitoring page is accessible without user authentication, but inside listener we are getting not authorised exception like:

javax.ejb.AccessLocalException:  ; nested exception is: com.ibm.websphere.csi.CSIAccessException: SECJ0053E: Authorization failed for None/server:iap_iapnode0_server while invoking (Bean)Prj#EJB.jar#ServiceController stopTimers::3  is not granted any of the required roles: user
at com.ibm.ws.security.core.SecurityCollaborator.performAuthorization(SecurityCollaborator.java:626)
at com.ibm.ws.security.core.EJSSecurityCollaborator.preInvoke(EJSSecurityCollaborator.java:265)
at com.ibm.ejs.container.EJSContainer.preInvokeAfterActivate(EJSContainer.java:4214)
at com.ibm.ejs.container.EJSContainer.EjbPreInvoke(EJSContainer.java:3481)
at business.EJSLocalCSLServiceController_f7e0e567.stopTimers(EJSLocalCSLItrServiceController_f7e0e567.java)
at monitoring.servlet.TimerControlListener.contextInitialized(TimerControlListener.java:70)
at com.ibm.ws.webcontainer.webapp.WebApp.notifyServletContextCreated(WebApp.java:1686)
at com.ibm.ws.webcontainer.webapp.WebAppImpl.initialize(WebAppImpl.java:410)
at com.ibm.ws.webcontainer.webapp.WebGroupImpl.addWebApplication(WebGroupImpl.java:88)
at com.ibm.ws.webcontainer.VirtualHostImpl.addWebApplication(VirtualHostImpl.java:169)
at com.ibm.ws.webcontainer.WSWebContainer.addWebApp(WSWebContainer.java:749)
at com.ibm.ws.webcontainer.WSWebContainer.addWebApplication(WSWebContainer.java:634)
at com.ibm.ws.webcontainer.component.WebContainerImpl.install(WebContainerImpl.java:422)
at com.ibm.ws.webcontainer.component.WebContainerImpl.start(WebContainerImpl.java:714)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:1164)
at com.ibm.ws.runtime.component.DeployedApplicationImpl.fireDeployedObjectStart(DeployedApplicationImpl.java:1369)
at com.ibm.ws.runtime.component.DeployedModuleImpl.start(DeployedModuleImpl.java:639)
at com.ibm.ws.runtime.component.DeployedApplicationImpl.start(DeployedApplicationImpl.java:967)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplication(ApplicationMgrImpl.java:770)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplicationDynamically(ApplicationMgrImpl.java:1361)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:2162)
at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:446)
at com.ibm.ws.runtime.component.CompositionUnitImpl.start(CompositionUnitImpl.java:123)
at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:389)
at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.access$500(CompositionUnitMgrImpl.java:117)
at com.ibm.ws.runtime.component.CompositionUnitMgrImpl$1.run(CompositionUnitMgrImpl.java:664)
at com.ibm.ws.security.auth.ContextManagerImpl.runAs(ContextManagerImpl.java:5468)
at com.ibm.ws.security.auth.ContextManagerImpl.runAsSystem(ContextManagerImpl.java:5594)
at com.ibm.ws.security.core.SecurityContext.runAsSystem(SecurityContext.java:255)
at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.startCompositionUnit(CompositionUnitMgrImpl.java:678)
at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.startCompositionUnit(CompositionUnitMgrImpl.java:622)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplication(ApplicationMgrImpl.java:1251)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:69)
at sun.reflect.GeneratedMethodAccessor54.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:272)
at javax.management.modelmbean.RequiredModelMBean$4.run(RequiredModelMBean.java:1152)
at java.security.AccessController.doPrivileged(AccessController.java:298)
at com.ibm.oti.security.CheckedAccessControlContext.securityCheck(CheckedAccessControlContext.java:30)
at sun.misc.JavaSecurityAccessWrapper.doIntersectionPrivilege(JavaSecurityAccessWrapper.java:41)
at javax.management.modelmbean.RequiredModelMBean.invokeMethod(RequiredModelMBean.java:1146)
at javax.management.modelmbean.RequiredModelMBean.invoke(RequiredModelMBean.java:999)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:847)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:783)
at com.ibm.ws.management.AdminServiceImpl$1.run(AdminServiceImpl.java:1335)
at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:118)
at com.ibm.ws.management.AdminServiceImpl.invoke(AdminServiceImpl.java:1228)
at com.ibm.ws.management.commands.AdminServiceCommands$InvokeCmd.execute(AdminServiceCommands.java:251)
at com.ibm.ws.console.core.mbean.MBeanHelper.invoke(MBeanHelper.java:241)
at com.ibm.ws.console.appdeployment.ApplicationDeploymentCollectionAction.execute(ApplicationDeploymentCollectionAction.java:578)
at org.apache.struts.action.RequestProcessor.processActionPerform(Unknown Source)
at org.apache.struts.action.RequestProcessor.process(Unknown Source)
at org.apache.struts.action.ActionServlet.process(Unknown Source)
at org.apache.struts.action.ActionServlet.doPost(Unknown Source)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:595)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1230)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:779)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:478)
at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:178)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.invokeTarget(WebAppFilterChain.java:136)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:79)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:960)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1064)
at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.dispatch(WebAppRequestDispatcher.java:1385)
at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java:194)
at org.apache.struts.action.RequestProcessor.doForward(Unknown Source)
at org.apache.struts.tiles.TilesRequestProcessor.doForward(Unknown Source)
at org.apache.struts.action.RequestProcessor.processForwardConfig(Unknown Source)
at org.apache.struts.tiles.TilesRequestProcessor.processForwardConfig(Unknown Source)
at org.apache.struts.action.RequestProcessor.process(Unknown Source)
at org.apache.struts.action.ActionServlet.process(Unknown Source)
at org.apache.struts.action.ActionServlet.doPost(Unknown Source)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:595)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1230)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:779)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:478)
at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:178)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.invokeTarget(WebAppFilterChain.java:136)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:97)
at com.ibm.ws.console.core.servlet.WSCUrlFilter.setUpCommandAssistance(WSCUrlFilter.java:955)
at com.ibm.ws.console.core.servlet.WSCUrlFilter.continueStoringTaskState(WSCUrlFilter.java:504)
at com.ibm.ws.console.core.servlet.WSCUrlFilter.doFilter(WSCUrlFilter.java:325)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:195)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:91)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:960)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1064)
at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:87)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:914)
at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1662)
at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:200)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:453)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:515)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:306)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java:277)
at com.ibm.ws.ssl.channel.impl.SSLConnectionLink.determineNextChannel(SSLConnectionLink.java:1049)
at com.ibm.ws.ssl.channel.impl.SSLConnectionLink$MyReadCompletedCallback.complete(SSLConnectionLink.java:643)
at com.ibm.ws.ssl.channel.impl.SSLReadServiceContext$SSLReadCompletedCallback.complete(SSLReadServiceContext.java:1819)
at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:175)
at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)
at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138)
at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204)
at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775)
at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:905)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1702)
Caused by: com.ibm.websphere.csi.CSIAccessException: SECJ0053E: Authorization failed for None/server:iap_iapnode0_xd while invoking (Bean)InDiaPrj#InDiaTBItrEJB.jar#ItrServiceController stopTimers::3  is not granted any of the required roles: user
... 112 more

Body:
Context listener cannot have any run as role associated with it.
You are trying to invoke  (Bean)Prj#EJB.jar#ServiceController stopTimers from that context listener, which looks like is secured and requires user which is not accessible by anonymous users.

So you have following solutions:

1) Use programmatic login in your context, with similar code to this:

// create login context
LoginContext lc = new LoginContext( "WSLogin", new WSCallbackHandlerImpl(userid, password));
// do login
lc.login();
// retrieve subject
Subject subject = lc.getSubject();
// set new identity
WSSubject.setRunAsSubject(subject);
// call session bean
itrServiceController.stopTimers();
// logout - destroy credentials
lc.logout();

2) Use intermediate servlet or EJB with runas role set.

So from your listener you just call servlet or local session bean, which will have runAs role set, and that bean will simply call your ItrServiceController using associated with role user.

This is probably easier as it allows to define that user/role mapping on deployment.


问:
Changing visibility of java 8 default method
I have a class (Say FOO) and it has a method with default visibility,
like below :

```<code>void sayHi() {}
</code>```

Now, If a override this method in extending class I cannot decrease it's visibility. So I can only use default or public.

```<code>public class MyClassTest extends FOO {
    @Override
    // Or I can use public void sayHi()
    void sayHi() {
        System.out.println("Overriden sayHi");
    }
}
</code>```

Now if I write an Interface in Java 8 with a default method like below :

```<code>public interface InterfaceX {

    // Java-8 defalu method
    default String printName() {
        System.out.println("Interface1 default metod");
        return "Interface1 default metod";
    }
}
</code>```

Now, if I override this method in a class It should compile if a keep overridden method's visibility default.

```<code>public class Java8InterfaceTest implements InterfaceX{
    @Override
     void printHello() {
        System.out.println("Printing..!");
        Interface1.super.printName();
    }
 }
</code>```

It says

Cannot reduce the visibility of the inherited method from InterfaceX

I already know that every method in interface in public by default, but in the above example we are using default which I think is one of the access modifier in java.

I have following questions:

Is default in interface different from default visibility which is provide when no access modifier applied?

If it's different then how it's different?

答:
The other answers nicely outline that "syntactical" flaw in your assumption about default being a "visibility" thing.

But there is a conceptual problem behind that worth a dedicated answer: it is not sound to reduce the visibility of methods.

Keep in mind: the pubic "API" of a class or an interface declares a contract for client code to work with. Like: having a method eat() on a base class/interface Animal.

The whole point is that different subclasses/implementations can provide their own implementation of eat(). So that you can have:

```<code>Animal whatever = ...
whatever.eat();
</code>```

And no matter what ... is actually creating (could be Cat, Dog, Unicorn) - it is valid to call whatever.eat().

Your idea is to say: I want to "hide" eat() for a specific subclass Donkey. If you could do that - all of a sudden the above code might be invalid. Because whatever.eat() is no longer a valid call when whatever happens to be an instance of Donkey.

Long story short: read about the Liskov Substitution Principle to understand why "taking away" public is not a good idea - completely independent from mixing up "default package protected visibility" and
the default keyword in interfaces.

Body:
I have a class (Say FOO) and it has a method with default visibility,
like below :

void sayHi() {}

Now, If a override this method in extending class I cannot decrease it's visibility. So I can only use default or public.

public class MyClassTest extends FOO {
    @Override
    // Or I can use public void sayHi()
    void sayHi() {
        System.out.println("Overriden sayHi");
    }
}

Now if I write an Interface in Java 8 with a default method like below :

public interface InterfaceX {

    // Java-8 defalu method
    default String printName() {
        System.out.println("Interface1 default metod");
        return "Interface1 default metod";
    }
}

Now, if I override this method in a class It should compile if a keep overridden method's visibility default.

public class Java8InterfaceTest implements InterfaceX{
    @Override
     void printHello() {
        System.out.println("Printing..!");
        Interface1.super.printName();
    }
 }

It says

Cannot reduce the visibility of the inherited method from InterfaceX

I already know that every method in interface in public by default, but in the above example we are using default which I think is one of the access modifier in java.

I have following questions:

Is default in interface different from default visibility which is provide when no access modifier applied?

If it's different then how it's different?

Body:
The other answers nicely outline that "syntactical" flaw in your assumption about default being a "visibility" thing.

But there is a conceptual problem behind that worth a dedicated answer: it is not sound to reduce the visibility of methods.

Keep in mind: the pubic "API" of a class or an interface declares a contract for client code to work with. Like: having a method eat() on a base class/interface Animal.

The whole point is that different subclasses/implementations can provide their own implementation of eat(). So that you can have:

Animal whatever = ...
whatever.eat();

And no matter what ... is actually creating (could be Cat, Dog, Unicorn) - it is valid to call whatever.eat().

Your idea is to say: I want to "hide" eat() for a specific subclass Donkey. If you could do that - all of a sudden the above code might be invalid. Because whatever.eat() is no longer a valid call when whatever happens to be an instance of Donkey.

Long story short: read about the Liskov Substitution Principle to understand why "taking away" public is not a good idea - completely independent from mixing up "default package protected visibility" and
the default keyword in interfaces.


问:
Bokeh scatterplot with gradient colors
I'm trying to make a scatter plot with Bokeh. For example:

```<code>from bokeh.plotting import figure, show, output_notebook

TOOLS='pan,wheel_zoom,box_zoom,reset'
p = figure(tools=TOOLS)

p.scatter(x=somedata.x, y=somedata.y)
</code>```

Ideally, I'd like to color with stronger intensity as the data approaches its maximum/minimum value of y. For example from red to blue (-1 to 1), just like in a heatmap (parameters vmax and vmin).

Is there an easy way of doing it?

答:
Bokeh has an inbuilt functionality for mapping values to colors, and then applying these to the plot glyphs.

You can alternatively create a list of colors for each point, and pass these in if you don't want to use this features.

See below a simple example:

```<code>import numpy as np
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, LinearColorMapper

TOOLS='pan,wheel_zoom,box_zoom,reset'
p = figure(tools=TOOLS)

x = np.linspace(-10,10,200)
y = -x**2

data_source = ColumnDataSource({'x':x,'y':y})

color_mapper = LinearColorMapper(palette='Magma256', low=min(y), high=max(y))

# specify that we want to map the colors to the y values,
# this could be replaced with a list of colors
p.scatter(x,y,color={'field': 'y', 'transform': color_mapper})

show(p)
</code>```

Title: Bokeh scatterplot with gradient colors

Body:
I'm trying to make a scatter plot with Bokeh. For example:

from bokeh.plotting import figure, show, output_notebook

TOOLS='pan,wheel_zoom,box_zoom,reset'
p = figure(tools=TOOLS)

p.scatter(x=somedata.x, y=somedata.y)

Ideally, I'd like to color with stronger intensity as the data approaches its maximum/minimum value of y. For example from red to blue (-1 to 1), just like in a heatmap (parameters vmax and vmin).

Is there an easy way of doing it?

Body:
Bokeh has an inbuilt functionality for mapping values to colors, and then applying these to the plot glyphs.

You can alternatively create a list of colors for each point, and pass these in if you don't want to use this features.

See below a simple example:

import numpy as np
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, LinearColorMapper

TOOLS='pan,wheel_zoom,box_zoom,reset'
p = figure(tools=TOOLS)

x = np.linspace(-10,10,200)
y = -x**2

data_source = ColumnDataSource({'x':x,'y':y})

color_mapper = LinearColorMapper(palette='Magma256', low=min(y), high=max(y))

# specify that we want to map the colors to the y values,
# this could be replaced with a list of colors
p.scatter(x,y,color={'field': 'y', 'transform': color_mapper})

show(p)


问:
Is it possible in chartjs to hide certain dataset legends?
Is it possible to only hide certain dataset legends in chartjs? I know it is possible to hide all with </p>

```<code>options: {
    legend: {
        display: false
</code>```

答:
Short answer: Yes it is possible. Unfortunately it's not quite as simple as the developers could make it.

If you know what the text value of the item being displayed in the legend  is, then you can filter that out. After reading through the Chart.js docs I found the section Legend Label Configuration that details a filter function that can be used to "filter out the legend items", although this function must be set on the parent chart options object, not as an option on the dataset itself:

const chart = new Chart(ctx, {
    type: 'bar',
    data: data,
    options: {
        legend: {
            labels: {
                filter: function(item, chart) {
                    // Logic to remove a particular legend item goes here
                    return !item.text.includes('label to remove');
                }
            }
        }
    }
});
```

Now it appears each time the data changes and the chart is updated via chart.update() this filter function is called.

For convenience I have set this up in a jsfiddle for you to play with.

Note: This solution was designed around the API for version 2.7.1 of ChartJS. Future versions may improve the control over dataset legend labels.

Body:
Is it possible to only hide certain dataset legends in chartjs? I know it is possible to hide all with

options: {
    legend: {
        display: false

Body:
Short answer: Yes it is possible. Unfortunately it's not quite as simple as the developers could make it.

If you know what the text value of the item being displayed in the legend  is, then you can filter that out. After reading through the Chart.js docs I found the section Legend Label Configuration that details a filter function that can be used to "filter out the legend items", although this function must be set on the parent chart options object, not as an option on the dataset itself:

const chart = new Chart(ctx, {
    type: 'bar',
    data: data,
    options: {
        legend: {
            labels: {
                filter: function(item, chart) {
                    // Logic to remove a particular legend item goes here
                    return !item.text.includes('label to remove');
                }
            }
        }
    }
});

Now it appears each time the data changes and the chart is updated via chart.update() this filter function is called.

For convenience I have set this up in a jsfiddle for you to play with.

Note: This solution was designed around the API for version 2.7.1 of ChartJS. Future versions may improve the control over dataset legend labels.

ContentLicense: CC BY-SA 4.0


问:
How to configure kubernetes kub-dns to reach external net?
I tried examples via windows minikube.

at minikube ssh, I can ping google.com.

but at Inside the container, I cant ping yahoo.com , what should i do?

Need help please.

Regards.

This is logs

答: fixed at minikube version: v0.24.1</p>

Body: fixed at minikube version: v0.24.1


问:
How to get response of observable in Angular2?
I have consumed an http url having json response

```<code> [
    {
    _id: "5a22ff88a06b10436a9da55f",
    updatedOn: "2017-12-02T19:31:20.026Z",
    createdOn: "2017-12-02T19:31:20.026Z",
    createdBy: "Vishal Patel",
    status: "o",
    penddate: "2017-12-20T00:00:00.000Z",
    pstartdate: "2017-12-03T00:00:00.000Z",
    name: "vishal patel",
    epmid: "e100",
    pid: "1000",
    __v: 0
    }
    ]
</code>```

in .service.ts file using the following code

```<code>getProjects(): Observable<MaterialList[]>
{
return this.http.get<MaterialList[]>(this.url)
.pipe(
tap(projectlist => this.log(`FetchedList`)),
catchError(this.handleError('getProjects',[]))
);

}
</code>```

in abc.component.ts file

used this

```<code>projectlist: MaterialList[] = [];

this.getProjectsList.getProjects().subscribe(projectlist => this.prrojectlist = projectlist['']);
</code>```

I have checked using this as well

```<code>this.getProjectsList.getProjects().subscribe(projectlist => { this.prrojectlist = projectlist['']});
</code>```

but not able to get response in this.projectlist.

I have followed heroes tutorial from angular.io

Please help I am new to Angular2 typescript2.

答:
You have assigned blank array to your result array.

Please modify your code from this this.getProjectsList.getProjects().subscribe(projectlist => this.prrojectlist = projectlist['']); to this this.getProjectsList.getProjects().subscribe((data) => this.prrojectlist = data);

Body:
I have consumed an http url having json response

 [
    {
    _id: "5a22ff88a06b10436a9da55f",
    updatedOn: "2017-12-02T19:31:20.026Z",
    createdOn: "2017-12-02T19:31:20.026Z",
    createdBy: "Vishal Patel",
    status: "o",
    penddate: "2017-12-20T00:00:00.000Z",
    pstartdate: "2017-12-03T00:00:00.000Z",
    name: "vishal patel",
    epmid: "e100",
    pid: "1000",
    __v: 0
    }
    ]

in .service.ts file using the following code

getProjects(): Observable<MaterialList[]>
{
return this.http.get<MaterialList[]>(this.url)
.pipe(
tap(projectlist => this.log(`FetchedList`)),
catchError(this.handleError('getProjects',[]))
);

}

in abc.component.ts file

used this

projectlist: MaterialList[] = [];

this.getProjectsList.getProjects().subscribe(projectlist => this.prrojectlist = projectlist['']);

I have checked using this as well

this.getProjectsList.getProjects().subscribe(projectlist => { this.prrojectlist = projectlist['']});

but not able to get response in this.projectlist.

I have followed heroes tutorial from angular.io

Please help I am new to Angular2 typescript2.


问:
Discovering Generic Controllers in ASP.NET Core
I am trying to create a generic controller like this:

```<code>[Route("api/[controller]")]
public class OrdersController<T> : Controller where T : IOrder
{
    [HttpPost("{orderType}")]
    public async Task<IActionResult> Create(
        [FromBody] Order<T> order)
    {
       //....
    }
}
</code>```

I intend for the {orderType} URI segment variable to control the generic type of the controller.  I'm experimenting with both a custom IControllerFactory and IControllerActivator, but nothing is working.  Every time I try to send a request, I get a 404 response.  The code for my custom controller factory (and activator) is never executed.

Evidently the problem is that ASP.NET Core expects valid controllers to end with the suffix "Controller", but my generic controller instead has the (reflection based) suffix "Controller`1".  Thus the attribute-based routes it declares are going unnoticed.

In ASP.NET MVC, at least in its early days, the DefaultControllerFactory was responsible for discovering all the available controllers.  It tested for the "Controller" suffix:

The MVC framework provides a default controller factory (aptly named DefaultControllerFactory) that will search through all the assemblies in an appdomain looking for all types that implement IController and whose name ends with "Controller."

Apparently, in ASP.NET Core, the controller factory no longer has this responsibility.  As I stated earlier, my custom controller factory executes for "normal" controllers, but is never invoked for generic controllers.  So there is something else, earlier in the evaluation process, which governs the discovery of controllers.

Does anyone know what "service" interface is responsible for that discovery?  I don't know the customization interface or "hook" point.

And does anyone know of a way to make ASP.NET Core "dump" the names of all the controllers it discovered?  It would be great to write a unit test that verifies that any custom controller discovery I expect is indeed working.

Incidentally, if there is a "hook" which allows generic controller names to be discovered, it implies that route substitutions must also be normalized:

```<code>[Route("api/[controller]")]
public class OrdersController<T> : Controller { }
</code>```

Regardless of what value for T is given, the [controller] name must remain a simple base-generic name.  Using the above code as an example, the [controller] value would be "Orders".  It would not be "Orders`1" or "OrdersOfSomething".

Note

This problem could also be solved by explicitly declaring the closed-generic types, instead of generating them at run time:

```<code>public class VanityOrdersController : OrdersController<Vanity> { }
public class ExistingOrdersController : OrdersController<Existing> { }
</code>```

The above works, but it produces URI paths that I don't like:

```<code>~/api/VanityOrders
~/api/ExistingOrders
</code>```

What I had actually wanted was this:

```<code>~/api/Orders/Vanity
~/api/Orders/Existing
</code>```

Another adjustment gets me the URI's I'm looking for:

```<code>[Route("api/Orders/Vanity", Name ="VanityLink")]
public class VanityOrdersController : OrdersController<Vanity> { }
[Route("api/Orders/Existing", Name = "ExistingLink")]
public class ExistingOrdersController : OrdersController<Existing> { }
</code>```

However, although this appears to work, it does not really answer my question.  I would like to use my generic controller directly at run-time, rather than indirectly (via manual coding) at compile-time.  Fundamentally, this means I need ASP.NET Core to be able to "see" or "discover" my generic controller, despite the fact that its run-time reflection name does not end with the expected "Controller" suffix.

答:
Application Feature Providers examine application parts and provide features for those parts. There are built-in feature providers for the following MVC features:

Controllers

Metadata Reference

Tag Helpers

View Components

Feature providers inherit from IApplicationFeatureProvider, where T is the type of the feature. You can implement your own feature providers for any of MVC's feature types listed above. The order of feature providers in the ApplicationPartManager.FeatureProviders collection can be important, since later providers can react to actions taken by previous providers.

By default, ASP.NET Core MVC ignores generic controllers (for example, SomeController). This sample uses a controller feature provider that runs after the default provider and adds generic controller instances for a specified list of types (defined in EntityTypes.Types):

```<code>public class GenericControllerFeatureProvider : IApplicationFeatureProvider<ControllerFeature>
{
    public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
    {
        // This is designed to run after the default ControllerTypeProvider,
        // so the list of 'real' controllers has already been populated.
        foreach (var entityType in EntityTypes.Types)
        {
            var typeName = entityType.Name + "Controller";
            if (!feature.Controllers.Any(t => t.Name == typeName))
            {
                // There's no 'real' controller for this entity, so add the generic version.
                var controllerType = typeof(GenericController<>)
                    .MakeGenericType(entityType.AsType()).GetTypeInfo();
                feature.Controllers.Add(controllerType);
            }
        }
    }
}
</code>```

The entity types:

```<code>public static class EntityTypes
{
    public static IReadOnlyList<TypeInfo> Types => new List<TypeInfo>()
    {
        typeof(Sprocket).GetTypeInfo(),
        typeof(Widget).GetTypeInfo(),
    };

    public class Sprocket { }
    public class Widget { }
}
</code>```

The feature provider is added in Startup:

```<code>services.AddMvc()
    .ConfigureApplicationPartManager(p =>
        p.FeatureProviders.Add(new GenericControllerFeatureProvider()));
</code>```

By default, the generic controller names used for routing would be of the form GenericController`1[Widget] instead of Widget. The following attribute is used to modify the name to correspond to the generic type used by the controller:

using Microsoft.AspNetCore.Mvc.ApplicationModels;
using System;

```<code>namespace AppPartsSample
{
    // Used to set the controller name for routing purposes. Without this convention the
    // names would be like 'GenericController`1[Widget]' instead of 'Widget'.
    //
    // Conventions can be applied as attributes or added to MvcOptions.Conventions.
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
    public class GenericControllerNameConvention : Attribute, IControllerModelConvention
    {
        public void Apply(ControllerModel controller)
        {
            if (controller.ControllerType.GetGenericTypeDefinition() !=
                typeof(GenericController<>))
            {
                // Not a GenericController, ignore.
                return;
            }

            var entityType = controller.ControllerType.GenericTypeArguments[0];
            controller.ControllerName = entityType.Name;
        }
    }
}
</code>```

The GenericController class:

```<code>using Microsoft.AspNetCore.Mvc;

namespace AppPartsSample
{
    [GenericControllerNameConvention] // Sets the controller name based on typeof(T).Name
    public class GenericController<T> : Controller
    {
        public IActionResult Index()
        {
            return Content($"Hello from a generic {typeof(T).Name} controller.");
        }
    }
}
</code>```

Sample: Generic controller feature

Body:
I am trying to create a generic controller like this:

[Route("api/[controller]")]
public class OrdersController<T> : Controller where T : IOrder
{
    [HttpPost("{orderType}")]
    public async Task<IActionResult> Create(
        [FromBody] Order<T> order)
    {
       //....
    }
}

I intend for the {orderType} URI segment variable to control the generic type of the controller.  I'm experimenting with both a custom IControllerFactory and IControllerActivator, but nothing is working.  Every time I try to send a request, I get a 404 response.  The code for my custom controller factory (and activator) is never executed.

Evidently the problem is that ASP.NET Core expects valid controllers to end with the suffix "Controller", but my generic controller instead has the (reflection based) suffix "Controller`1".  Thus the attribute-based routes it declares are going unnoticed.

In ASP.NET MVC, at least in its early days, the DefaultControllerFactory was responsible for discovering all the available controllers.  It tested for the "Controller" suffix:

The MVC framework provides a default controller factory (aptly named DefaultControllerFactory) that will search through all the assemblies in an appdomain looking for all types that implement IController and whose name ends with "Controller."

Apparently, in ASP.NET Core, the controller factory no longer has this responsibility.  As I stated earlier, my custom controller factory executes for "normal" controllers, but is never invoked for generic controllers.  So there is something else, earlier in the evaluation process, which governs the discovery of controllers.

Does anyone know what "service" interface is responsible for that discovery?  I don't know the customization interface or "hook" point.

And does anyone know of a way to make ASP.NET Core "dump" the names of all the controllers it discovered?  It would be great to write a unit test that verifies that any custom controller discovery I expect is indeed working.

Incidentally, if there is a "hook" which allows generic controller names to be discovered, it implies that route substitutions must also be normalized:

[Route("api/[controller]")]
public class OrdersController<T> : Controller { }

Regardless of what value for T is given, the [controller] name must remain a simple base-generic name.  Using the above code as an example, the [controller] value would be "Orders".  It would not be "Orders`1" or "OrdersOfSomething".

Note

This problem could also be solved by explicitly declaring the closed-generic types, instead of generating them at run time:

public class VanityOrdersController : OrdersController<Vanity> { }
public class ExistingOrdersController : OrdersController<Existing> { }

The above works, but it produces URI paths that I don't like:

~/api/VanityOrders
~/api/ExistingOrders

What I had actually wanted was this:

~/api/Orders/Vanity
~/api/Orders/Existing

Another adjustment gets me the URI's I'm looking for:

[Route("api/Orders/Vanity", Name ="VanityLink")]
public class VanityOrdersController : OrdersController<Vanity> { }
[Route("api/Orders/Existing", Name = "ExistingLink")]
public class ExistingOrdersController : OrdersController<Existing> { }

However, although this appears to work, it does not really answer my question.  I would like to use my generic controller directly at run-time, rather than indirectly (via manual coding) at compile-time.  Fundamentally, this means I need ASP.NET Core to be able to "see" or "discover" my generic controller, despite the fact that its run-time reflection name does not end with the expected "Controller" suffix.

Body:
Application Feature Providers examine application parts and provide features for those parts. There are built-in feature providers for the following MVC features:

Controllers

Metadata Reference

Tag Helpers

View Components

Feature providers inherit from IApplicationFeatureProvider, where T is the type of the feature. You can implement your own feature providers for any of MVC's feature types listed above. The order of feature providers in the ApplicationPartManager.FeatureProviders collection can be important, since later providers can react to actions taken by previous providers.

By default, ASP.NET Core MVC ignores generic controllers (for example, SomeController). This sample uses a controller feature provider that runs after the default provider and adds generic controller instances for a specified list of types (defined in EntityTypes.Types):

public class GenericControllerFeatureProvider : IApplicationFeatureProvider<ControllerFeature>
{
    public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
    {
        // This is designed to run after the default ControllerTypeProvider,
        // so the list of 'real' controllers has already been populated.
        foreach (var entityType in EntityTypes.Types)
        {
            var typeName = entityType.Name + "Controller";
            if (!feature.Controllers.Any(t => t.Name == typeName))
            {
                // There's no 'real' controller for this entity, so add the generic version.
                var controllerType = typeof(GenericController<>)
                    .MakeGenericType(entityType.AsType()).GetTypeInfo();
                feature.Controllers.Add(controllerType);
            }
        }
    }
}

The entity types:

public static class EntityTypes
{
    public static IReadOnlyList<TypeInfo> Types => new List<TypeInfo>()
    {
        typeof(Sprocket).GetTypeInfo(),
        typeof(Widget).GetTypeInfo(),
    };

    public class Sprocket { }
    public class Widget { }
}

The feature provider is added in Startup:

services.AddMvc()
    .ConfigureApplicationPartManager(p =>
        p.FeatureProviders.Add(new GenericControllerFeatureProvider()));

By default, the generic controller names used for routing would be of the form GenericController`1[Widget] instead of Widget. The following attribute is used to modify the name to correspond to the generic type used by the controller:

using Microsoft.AspNetCore.Mvc.ApplicationModels;
using System;

namespace AppPartsSample
{
    // Used to set the controller name for routing purposes. Without this convention the
    // names would be like 'GenericController`1[Widget]' instead of 'Widget'.
    //
    // Conventions can be applied as attributes or added to MvcOptions.Conventions.
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
    public class GenericControllerNameConvention : Attribute, IControllerModelConvention
    {
        public void Apply(ControllerModel controller)
        {
            if (controller.ControllerType.GetGenericTypeDefinition() !=
                typeof(GenericController<>))
            {
                // Not a GenericController, ignore.
                return;
            }

            var entityType = controller.ControllerType.GenericTypeArguments[0];
            controller.ControllerName = entityType.Name;
        }
    }
}

The GenericController class:

using Microsoft.AspNetCore.Mvc;

namespace AppPartsSample
{
    [GenericControllerNameConvention] // Sets the controller name based on typeof(T).Name
    public class GenericController<T> : Controller
    {
        public IActionResult Index()
        {
            return Content($"Hello from a generic {typeof(T).Name} controller.");
        }
    }
}

Sample: Generic controller feature


问:
Custom authorization with Azure AD authentication
I am developing a service fabric stateless web application using ASP.NET Core 2.0. This application is using Azure AD to authenticate users from multiple AD tenants. What I want to achieve is using my own role based authorization which can be configured in my application using the authorized user. These roles are stored in my application.

In my current implementation I add authorization to my application by adding a policy with my custom IAuthorizationRequirement. During the authorization of the requirement claims are added based on the users permissions. This means that claims are added post-login. The [Authorize(Roles = "role")] attribute also doesn't work because the role claims are added post-login

What is the correct way to implement this custom authorization which uses the authenticated user from Azure AD?

答:
You can add your own custom claims after the user signs in through the OnTokenValidated event:

```<code>.AddOpenIdConnect(o =>
{
    Configuration.GetSection("OpenIdConnect").Bind(o);
    o.Events = new OpenIdConnectEvents
    {
        OnTokenValidated = async ctx =>
        {
            string oid = ctx.Principal.FindFirstValue("http://schemas.microsoft.com/identity/claims/objectidentifier");

            var db = ctx.HttpContext.RequestServices.GetRequiredService<AuthorizationDbContext>();

            var objectIdGuid = Guid.Parse(oid);
            bool isSuperAdmin = await db.SuperAdmins.AnyAsync(a => a.ObjectId == objectIdGuid);
            if (isSuperAdmin)
            {
                var claims = new List<Claim>();
                claims.Add(new Claim(ClaimTypes.Role, Roles.SuperAdmin));
                var appIdentity = new ClaimsIdentity(claims, "MyTestAppIdentity");

                ctx.Principal.AddIdentity(appIdentity);
            }
        }
    };
});
</code>```

Here as an example we check from a database whether the user is a super admin. Then if they are, we create a new identity for them with the necessary role as a claim.

All the identities are combined on the principal to produce their claim set, so all the other claims will still be available too.

Body:
You can add your own custom claims after the user signs in through the OnTokenValidated event:

.AddOpenIdConnect(o =>
{
    Configuration.GetSection("OpenIdConnect").Bind(o);
    o.Events = new OpenIdConnectEvents
    {
        OnTokenValidated = async ctx =>
        {
            string oid = ctx.Principal.FindFirstValue("http://schemas.microsoft.com/identity/claims/objectidentifier");

            var db = ctx.HttpContext.RequestServices.GetRequiredService<AuthorizationDbContext>();

            var objectIdGuid = Guid.Parse(oid);
            bool isSuperAdmin = await db.SuperAdmins.AnyAsync(a => a.ObjectId == objectIdGuid);
            if (isSuperAdmin)
            {
                var claims = new List<Claim>();
                claims.Add(new Claim(ClaimTypes.Role, Roles.SuperAdmin));
                var appIdentity = new ClaimsIdentity(claims, "MyTestAppIdentity");

                ctx.Principal.AddIdentity(appIdentity);
            }
        }
    };
});

Here as an example we check from a database whether the user is a super admin. Then if they are, we create a new identity for them with the necessary role as a claim.

All the identities are combined on the principal to produce their claim set, so all the other claims will still be available too.


问:
Responsive Layout with same growing gaps in each row
I have a container with a random number of elements which should always align on the left side. The container width can increase or decrease.

If the container size is increasing then the first element from the row+1 should go one row back and should appear on the right side. But it should only go one row back if it can fit there with a padding on the left and right side.

While the element does not have space one row abouve, then the space between the elements should grow until the element from row+1 can fit in this row.

The same functionality should work also in the reverse way.

Here is my code:

.container {
  min-height: 400px;
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  justify-content: space-around;
  align-items: center;
  align-content: flex-start;
}

.container:after {
  display: block;
  content: " invisible node ";
  flex(999 999 auto);
}

.item {
  flex: 0 0 auto;
  margin: 5px;
  width: 50px;
  height: 50px;
  background-color: green;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div></code>```

https://jsfiddle.net/p6k537ep/

My Problem ist that in the second row the space between the elements is not the same as in the first row (It depends how many elements are there).

Edit:

But it is working that the elements from the second row can only move one row abouve if they have anough space. The Gap is growing in the correct way in the first row but not in the second one.

答:
AFAIK, this is not solvable in Flexbox without adding invisible non-semantic helper elements to hold the horizontal rhythm of the last row (with the same width and horizontal margins as .items, but zero height).

However, this is easily solvable in CSS Grid, which seems perfect for this:

.container {
  min-height: 400px;
  display: grid;
  grid-template-columns: repeat(auto-fill, 60px);
  justify-content: space-around;
  align-items: center;
  align-content: start;
}

.item {
  flex: 0 0 auto;
  margin: 5px;
  width: 50px;
  height: 50px;
  background-color: green;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div></code>```

and kind of solvable with inline-blocks, using the similar pseudo-element hack and some "magic" of the inline formatting:

.container {
  min-height: 400px;
  text-align: justify;
  font-size: 5px;
  line-height: 0;
}

.container:after {
  display: inline; /* it's important, it should continue the same line! */
  /* each character below acts as an invisible placeholder for the item */
  /* with em dashes, they would be 1em (5px here) wide each */
  content: '— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — ';
  letter-spacing: 55px; /* expand each placeholder to the item width */
  word-spacing: -56px; /* collapse the whitespaces */
  margin-left: 5px;
}

.item {
  display: inline-block;
  margin: 5px;
  width: 50px;
  height: 50px;
  background-color: green;
  vertical-align: top;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div></code>```

But, honestly, I'd not recommend using the second option in production. Left-aligning the items instead would probably be a better fallback for browsers that don't support Grid.

Body:
I have a container with a random number of elements which should always align on the left side. The container width can increase or decrease.

If the container size is increasing then the first element from the row+1 should go one row back and should appear on the right side. But it should only go one row back if it can fit there with a padding on the left and right side.

While the element does not have space one row abouve, then the space between the elements should grow until the element from row+1 can fit in this row.

The same functionality should work also in the reverse way.

Here is my code:

.container {
  min-height: 400px;
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  justify-content: space-around;
  align-items: center;
  align-content: flex-start;
}

.container:after {
  display: block;
  content: " invisible node ";
  flex(999 999 auto);
}

.item {
  flex: 0 0 auto;
  margin: 5px;
  width: 50px;
  height: 50px;
  background-color: green;
}

https://jsfiddle.net/p6k537ep/

My Problem ist that in the second row the space between the elements is not the same as in the first row (It depends how many elements are there).

Edit:

But it is working that the elements from the second row can only move one row abouve if they have anough space. The Gap is growing in the correct way in the first row but not in the second one.

Body:
AFAIK, this is not solvable in Flexbox without adding invisible non-semantic helper elements to hold the horizontal rhythm of the last row (with the same width and horizontal margins as .items, but zero height).

However, this is easily solvable in CSS Grid, which seems perfect for this:

.container {
  min-height: 400px;
  display: grid;
  grid-template-columns: repeat(auto-fill, 60px);
  justify-content: space-around;
  align-items: center;
  align-content: start;
}

.item {
  flex: 0 0 auto;
  margin: 5px;
  width: 50px;
  height: 50px;
  background-color: green;
}

<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

and kind of solvable with inline-blocks, using the similar pseudo-element hack and some "magic" of the inline formatting:

.container {
  min-height: 400px;
  text-align: justify;
  font-size: 5px;
  line-height: 0;
}

.container:after {
  display: inline; /* it's important, it should continue the same line! */
  /* each character below acts as an invisible placeholder for the item */
  /* with em dashes, they would be 1em (5px here) wide each */
  content: '— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — ';
  letter-spacing: 55px; /* expand each placeholder to the item width */
  word-spacing: -56px; /* collapse the whitespaces */
  margin-left: 5px;
}

.item {
  display: inline-block;
  margin: 5px;
  width: 50px;
  height: 50px;
  background-color: green;
  vertical-align: top;
}

<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

But, honestly, I'd not recommend using the second option in production. Left-aligning the items instead would probably be a better fallback for browsers that don't support Grid.