Java Reference incorrect - java

i'm using OWL-S API (source and javadoc here: http://on.cs.unibas.ch/owls-api/apidocs/ )
If i do this i have the correct result:
public class Example {
private static ISWRLFactory factory; //is a interface
private string url = "http://...";
private Service aService;
private OWLOntology ont;
void method_A(){
URI aURI = URI.create(url);
OWLKnowledgeBase aKB = OWLFactory.createKB();
aService = aKB.readService(aURI);
ont = aKB.createOntology(aURI);
ont.createService(aService.getURI());
}
void method_B(){
factory = SWRLFactory.createFactory(ont);
Atom builtAtom = factory.createNotEqual(x, variab); //x and variab are two variable
}
}
But if i do this i don't have the correct result:
public class Example {
private static ISWRLFactory factory; //is a interface
private string url = "http://...";
private Service aService;
private OWLOntology ont;
void method_A(){
URI aURI = URI.create(url);
OWLKnowledgeBase aKB = OWLFactory.createKB();
aService = aKB.readService(aURI);
ont = aKB.createOntology(aURI);
ont.createService(aService.getURI());
factory = SWRLFactory.createFactory(ont);
}
void method_B(){
Atom builtAtom = factory.createNotEqual(x, variab); //x and variab are two variable
}
}
Why?

Difference exist in executing " factory = SWRLFactory.createFactory(ont);" line in method_A() and method_B().
Are you sure 'factory' object is not modified between method_A() and method_B() calls? Does 'x' and 'variable' have some dependency on 'factory' ?

Related

Inject value into a static field

Here is my class:
public class DeduplicationErrorMetric extends AbstractErrorMetric {
public static final String DEDUPLICATIONS_METRIC = "deduplications";
public static final String KAFKA_MESSAGES_METRIC = "kafka.messages";
private static String DEDUPLICATION_TOPIC_NAME;
private static final List<Tag> DEDUPLICATION_ERROR_TAGS = List.of(Tag.of("type", "failed"));
private static final List<Tag> KAFKA_ERROR_TAGS = List.of(Tag.of("topic", DEDUPLICATION_TOPIC_NAME),
Tag.of("action", "send"), Tag.of("result", "failure"));
public DeduplicationErrorMetric() {
super(Map.of(
DEDUPLICATIONS_METRIC, DEDUPLICATION_ERROR_TAGS,
KAFKA_MESSAGES_METRIC, KAFKA_ERROR_TAGS
));
}
#Override
public void incrementMetric(String key) {
errorCounters.get(key).increment();
}
}
I have #Value("${kafka.topic.deduplication}") in my application.yml, and I need to insert the value into DEDUPLICATION_TOPIC_NAME before the bean will be created. How can I do it?
You can use the setter to do this but I'd advocate against this practice !
This means your field will be null before a first instance comes and invokes this injection point
Your static field is not final so can lead to modification, thus lead to hard to debug bugs
It will not solve your current problem as the null value will be used in this case for KAFKA_ERROR_TAGS
#Value("${kafka.topic.deduplication}")
private void setDeduplicationTopicName(String deduplicationTopicName) {
this.DEDUPLICATION_TOPIC_NAME = deducplicationTopicName;
}
Instead, maybe try to create a #Singleton bean and use #Value on its fields, then you're sure you have only one instance.
For your list, you can then use #PostConstruct to make sure it's instantiated once
What you could do here is to directly use injection from a properties file.
If it is a SpringBoot app, in you application properties set your kafka.topic.deduplication property (you can have different values for different environments).
This way, Spring will get the value while constructing the bean.
Your code could look something like this:
public class DeduplicationErrorMetric extends AbstractErrorMetric {
public static final String DEDUPLICATIONS_METRIC = "deduplications";
public static final String KAFKA_MESSAGES_METRIC = "kafka.messages";
private static final List<Tag> DEDUPLICATION_ERROR_TAGS = List.of(Tag.of("type", "failed"));
private static final List<Tag> KAFKA_ERROR_TAGS = List.of(Tag.of("topic", deduplicationTopicName),
Tag.of("action", "send"), Tag.of("result", "failure"));
#Value("${kafka.topic.deduplication}")
private String deduplicationTopicName;
public DeduplicationErrorMetric() {
super(Map.of(
DEDUPLICATIONS_METRIC, DEDUPLICATION_ERROR_TAGS,
KAFKA_MESSAGES_METRIC, KAFKA_ERROR_TAGS
));
}
#Override
public void incrementMetric(String key) {
errorCounters.get(key).increment();
}
}
Remove the keyword "static" and then you will be able to change it in the instance.
Static means that the field is locked to the class.
public class DeduplicationErrorMetric extends AbstractErrorMetric {
public static final String DEDUPLICATIONS_METRIC = "deduplications";
public static final String KAFKA_MESSAGES_METRIC = "kafka.messages";
private String DEDUPLICATION_TOPIC_NAME;
private static final List<Tag> DEDUPLICATION_ERROR_TAGS = List.of(Tag.of("type", "failed"));
private List<Tag> KAFKA_ERROR_TAGS = List.of(Tag.of("topic", DEDUPLICATION_TOPIC_NAME),
Tag.of("action", "send"), Tag.of("result", "failure"));
public DeduplicationErrorMetric() {
super(Map.of(
DEDUPLICATIONS_METRIC, DEDUPLICATION_ERROR_TAGS,
KAFKA_MESSAGES_METRIC, KAFKA_ERROR_TAGS
));
}
#Override
public void incrementMetric(String key) {
errorCounters.get(key).increment();
}
public void setTopic(String value){
DEDUPLICATION_TOPIC_NAME = value;
}
}
private void example(){
DeduplicationErrorMetric dem = new DeduplicationErrorMetric();
//Set the instance value directly
dem.DEDUPLICATION_TOPIC_NAME = "Test";
//Set via a function, potentially with other variables.
demo.setTopic("Test");
}
I would also recommend making the variable name lowercase now that it is not static, as good coding practice.

PowerMockito whenNew returns null

In the source class that which I can't refactor (so i can't use advices here) there are object creations with = new XXX. And i have to mock their function calls X().call().
For this purpose i am using powermock's whenNew() function. But i am having null in the class that i am testing which is LoginSuccessHandler in this case. Here my LoginSuccessHandlerTest class:
#RunWith(PowerMockRunner.class)
public class LoginSuccessHandlerTest {
#InjectMocks private LoginSuccessHandler loginSuccessHandler;
#Mock private GuiSessionDAO guiSessionDAO;
#Mock private UserAuthorityDAO userAuthorityDAO;
#Mock private OrcaAuthorizationServiceBean orcaAuthorizationServiceBean;
#Mock private OrcaAuthorizationServiceBeanService orcaAuthorizationServiceBeanService;
#Mock private GetUserRolesReturnModel userRolesReturnModel;
private Authentication authentication;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
#Before
public void setUp() {
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
authentication = new TestingAuthenticationToken("foo", "foo", "foo");
}
#PrepareForTest({LoginSuccessHandler.class})
#Test
public void onAuthenticationSuccess() throws Exception {
whenNew(OrcaAuthorizationServiceBeanService.class).withArguments(URL.class).thenReturn(orcaAuthorizationServiceBeanService);
p("Mocking Orca WS calls");
when(orcaAuthorizationServiceBeanService.getOrcaAuthorizationServiceBeanPort()).thenReturn(orcaAuthorizationServiceBean);
when(orcaAuthorizationServiceBean.getUserRoles(any(Header.class), anyString())).thenReturn(userRolesReturnModel);
when(userRolesReturnModel.getUserRoles()).thenReturn(Collections.singletonList("ADMIN"));
p("Starting mock log in");
loginSuccessHandler.onAuthenticationSuccess(request, response, authentication);
assertEquals(MockHttpServletResponse.SC_OK, response.getStatus());
}
private void p(String s) {
System.out.println(s);
}
And here i get null
OrcaAuthorizationServiceBeanService service = new OrcaAuthorizationServiceBeanService(new URL(url));
When i debug, i can confirm that powermockito is running to mock this object creation and this method is being called:
public static synchronized NewInvocationControl<?> putNewInstanceControl(Class<?> type, NewInvocationControl<?> control) {
return newSubstitutions.put(type, control);
}
And those are the parameters:
type = {Class#1755} "class com.ttech.timsgui.ldap.OrcaAuthorizationServiceBeanService"
cachedConstructor = null
newInstanceCallerCache = null
name = "com.ttech.timsgui.ldap.OrcaAuthorizationServiceBeanService"
classLoader = {MockClassLoader#2118}
reflectionData = {SoftReference#2119}
classRedefinedCount = 0
genericInfo = null
enumConstants = null
enumConstantDirectory = null
annotationData = null
annotationType = null
classValueMap = null
control = {MockitoNewInvocationControl#2093}
substitute = {InvocationSubstitute$$EnhancerByMockitoWithCGLIB$$4d9f6379#2109} "invocationSubstitute"
CGLIB$BOUND = true
CGLIB$CALLBACK_0 = {PowerMockMethodInterceptorFilter#2115}
CGLIB$CALLBACK_1 = {SerializableNoOp#2116}
And here is the result when it hits the getter:
public static synchronized NewInvocationControl<?> getNewInstanceControl(Class<?> type) {
return newSubstitutions.get(type);
}
type = {Class#277} "class java.net.URL"
newSubstitutions = {HashMap#1823} size = 1
0 = {HashMap$Node#2195} "class com.ttech.timsgui.ldap.OrcaAuthorizationServiceBeanService" ->
key = {Class#1755} "class com.ttech.timsgui.ldap.OrcaAuthorizationServiceBeanService"
value = {MockitoNewInvocationControl#2137}
this returns null and object creation returns null too. What causes this problem?
Try,
whenNew(OrcaAuthorizationServiceBeanService.class).withAnyArguments().thenReturn(orcaAuthorizationServiceBeanService);

JUnit Superclass mocked method still called

I'm trying to write my Unit Tests for a class which extends another. I'm calling a superclass method in another child class method :
The child class
#RestController
#RequestMapping(PUBLIC_BASE_URL)
public class RequeteSASRestController extends BaseController {
private static final Logger LOGGER = LogManager.getLogger();
private final RequeteSASService requeteSASService;
#Inject
public RequeteSASRestController(
final RequeteSASService pRequeteSASJdbcService) {
requeteSASService = pRequeteSASJdbcService;
}
#ApiOperation(value = "Lecture d'une liste des requetes SAS", responseContainer = "List")
#RequestMapping(value = "/statistiques/requeteSAS", method = RequestMethod.GET)
public ResponseEntity<SimpleServiceResponse<List<RequeteSAS>>> readListeRequeteSas() {
LOGGER.debug(" readListeRequeteSas() ->");
String remoteUser=super.getCurrentUserLogin();
return this.ok(requeteSASService.readListeRequeteSas(remoteUser));
}
The superclass
public class BaseController {
public String getCurrentUserLogin() {
//Some things
}
And finally here's my test class :
public class RequeteSASRestTest extends Mockito{
private RequeteSAS requeteSASJdbc1;
private RequeteSAS requeteSASJdbc2;
private RequeteSAS requeteSASJdbc1suppr;
/** Service RequeteSAS */
private RequeteSASService mockRequeteService;
/** Rest Controller. */
private RequeteSASRestController restController;
// Before : mock des services
#Before
public void beforeTests() throws FileNotFoundException {
clearSecurityContext();
mockRequeteService = mock(RequeteSASService.class);
restController = Mockito.spy(new RequeteSASRestController(mockRequeteService));
requeteSASJdbc1 = RequeteSASTestUtil.createRequeteSAS(//instance constructor);
requeteSASJdbc2 = RequeteSASTestUtil.createRequeteSAS(//instance constructor);
}
#Test
public void testGetRequetes() {
String mockRemoteUser = "STATT-00016-0102035";
List<RequeteSAS> listReqTest = new ArrayList<RequeteSAS>();
listReqTest.add(requeteSASJdbc1);
listReqTest.add(requeteSASJdbc2);
Mockito.doReturn(listReqTest).when(mockRequeteService).readListeRequeteSas(mockRemoteUser);
Mockito.doReturn(mockRemoteUser).when((BaseController)restController).getCurrentUserLogin();
ResponseEntity<SimpleServiceResponse<List<RequeteSAS>>> repReq = restController.readListeRequeteSas();
List<RequeteSAS> listReq = repReq.getBody().getValue();
//Assert List
}
As I said, with this, the method "getCurrentUserLogin()" from BaseController is still called, it does not return the mockRemoteUser. I've read many thread on this exact subject i.e. mocking a superclass method, I followed the answer, but still my test fails because "getCurrentUserLogin()" returns null instead of the mocked user.
Does somebody see where the problem is? Thank you.

servicefactories accessed from componet factory in OSGI

I am using component factory to create a multiple unique instances which in-turn uses services which is servicefactories to create multiple instance.
My structure looks like
TInterface - interface/service
TInterfaceInline - which implements TInterface also consists of #Reference for another service.
Tinterfaceimpl1 - extends TInterfaceInline which is a servicefactory with filter property.
TConsumer - component factory which consumes the TInterfaceInline
by getting it in #Reference.
TConsumer
#Component(name = "TConsumer", factory = "TConsumer")
#Service
public class TConsumer implements IConsumer {
// #Reference(bind = "bindInterface1", unbind = "unbindInterface1", target =
// "(className=Interface)")
// private Tinterface interface1;
#Reference(referenceInterface = ParentProfile.class, bind = "bindInterface11", unbind = "unbindInterface11", target = "(className=interface1)", policy = ReferencePolicy.STATIC, cardinality = ReferenceCardinality.MANDATORY_UNARY)
private ParentProfile interface11;
#Activate
public void activate(BundleContext aBundleContext) {
System.out.println("Object = " + interface11);
}
protected void bindInterface11(ParentProfile interface11) {
this.interface11 = interface11;
System.out.println("ref object11 created");
}
protected void unbindInterface11(ParentProfile interface11) {
interface11 = null;
}
TinterfaceImpl
#Component(name = "TInterfaceImol")
#Service(serviceFactory = true,value=ParentProfile.class)
#Properties(value = { #Property(name = "className", value = "interface1") })
public class Tinterfaceimpl1 extends TinterfaceInline {
public Tinterfaceimpl1() {
System.out.println("Generalprofile class : " + this);
}
}
TinterfaceInline
#Component(name = "TinterfaceInline ")
#Service
public class TinterfaceInline implements java.io.Serializable, ParentProfile {
// #Reference(bind = "bindtestin", unbind = "unbindtestin", cardinality =
// ReferenceCardinality.MANDATORY_UNARY, policy = ReferencePolicy.STATIC)
public Testint testin;
protected synchronized void bindtestin(Testint inter) {
this.testin = inter;
System.out.println("Profile Class : binded parameterresolver " + testin);
}
protected synchronized void unbindtestin(Testint inter) {
this.testin = inter;
}
}
ParentClass
#Component(name = "PResolver")
#Service
public class ProfileClass implements Testint {
public ProfileImpl() {
System.out.println("Parameter class impl : which extends ");
}
}
Apart from this remaining things are marker interfaces. If i try to install in karaf , the state of the Tinterfaceimpl1 is REGISTERED. ie) i am using servicefactories and accessing service factories from component factory. Servicefactory class extends a class which implements Interface. What is the reason Tinterfaceimpl1 is REGISTERED.

OSGi reading configurations

I am trying to code a OSGi bundle which can be initiated using multiple configurations. Purpose of my bundle is to rewrite static links in html and redirect it to a CDN URL. I am using org.apache.sling.rewriter.Transformer to achieve this.
#Component(metatype = true, label = "CDN Link Rewriter", configurationFactory = true, immediate = true)
#Service(value = TransformerFactory.class)
public class LinkTransformer implements Transformer,
TransformerFactory {
#Property(label = "Static URL Extensions", value = "js,jpg,png,css,gif")
private static final String STATIC_FILES_EXTNS = "static_file_extn";
#Property(label = "Domain Path", value = "")
private static final String DOMAIN_PATH = "domain_path";
#Property(label = "CDN Url prefix", value = "")
private static final String CDN_URL_PREFIX = "cdn_url_prefix";
#Property(label = "Tags to check", value = "a,img,link,script")
private static final String TAGS_TO_CHECK = "tags_to_check";
#Property(label = "Attributes to check", d value = "src,href")
private static final String ATTRS_TO_CHECK = "attrs_to_check";
#Property(value = "append-version", propertyPrivate = true)
private static final String PIPELINE_TYPE = "pipeline.type";
#Property(value = "global", propertyPrivate = true)
private static final String PIPELINE_MODE = "pipeline.mode";
#Activate
protected void activate(final Map<String, Object> props) {
this.update(props);
}
#Modified
protected void update(final Map<String, Object> props) {
}
public LinkTransformer() {
}
#Override
public void init(org.apache.sling.rewriter.ProcessingContext context,
org.apache.sling.rewriter.ProcessingComponentConfiguration config)
throws IOException {
}
#Override
public final Transformer createTransformer() {
return new LinkTransformer();
}
//some other methods
}
Problem: I am unable to access my configurations in my bundle. I am able to create multiple sets of configurations in Felix console. But #Activate method is called only at the time of bundle installation. During Link transformation activty only init() method is being called. Hence I am unable to get hold of configurations. Can anyone tell me how to get configurations ?
The problem with above approach is implementing to different interfaces in same class. Thanks to #Balazs Zsoldos you can check the answer here
Here, All I had to do was seperately implement Transformer and TransformerFactory.
#Component(configurationFactory = true, metatype = true, policy = ConfigurationPolicy.REQUIRE, label = "CDN Link Rewriter", description = "Rewrites links to all static files to use configurable CDN")
#Service(value = TransformerFactory.class)
public class StaticLinkTransformerFactory implements TransformerFactory {
//all property declarations as in question
private Map<String, Object> map;
#Activate
void activate(Map<String, Object> map) {
this.map = map;
}
#Override
public Transformer createTransformer() {
return new StaticLinkTransformer(map);
}
}
StaticLinkTransformer can be implemented as plain java class without any component or service annotations.

Categories