mercredi 1 mars 2017

Is Java automatically caching annotations and class metadata?

Java have a native support for annotations.

I'm wondering if when I call obj.getAnnotation(Annotation.class), java stores class metadata in any kind of cache.

I have the same question with reflection like:

for (Method method : obj.getDeclaredMethods()) {

        if (method.isAnnotationPresent(Annotation.class)) {

            Annotation annotation = method.getAnnotation(Annotation.class);
            Test test = (Test) annotation;

        }
}





Invoking a method from a string method name

I have a two sets of Urls one for PreProd and one for Prod. Each Url has several API nodes. Instead of hard coding these API nodes, I maintain them in an enum

Something like this:

//PreProd
 public enum PreProd
        {
            precheckorder,
            submitresubmit,
            creditInquiry,
            createupdateorder,
            confirmorder,
            getorderstatus,
            cancelorder,
        }

        /// <summary>
        /// Gets the relative URL.
        /// </summary>
        /// <param name="u">The u.</param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static string GetRelativeUrl(PreProd u)
        {
            switch (u)
            {
                case PreProd.precheckorder:
                    return "http://ift.tt/2mGaFQY";
                case PreProd.submitresubmit:
                    return "http://ift.tt/2meUw7z";
                case PreProd.creditInquiry:
                    return "http://ift.tt/2mGdr90";
                case PreProd.createupdateorder:
                    return "http://ift.tt/2mf06Hc";
                case PreProd.confirmorder:
                    return "http://ift.tt/2mG0LPj";
                case PreProd.getorderstatus:
                    return "http://ift.tt/2mfc97e";
                case PreProd.cancelorder:
                    return "http://ift.tt/2mGefKN";
                default:
                    // Handle bad URL, possibly throw
                    throw new Exception();
            }
        }

//Prod
        private enum Prod
        {
            precheckorder,
            submitresubmit,
            creditInquiry,
            createupdateorder,
            confirmorder,
            getorderstatus,
            cancelorder,
        }

        /// <summary>
        /// Gets the relative URL.
        /// </summary>
        /// <param name="u">The u.</param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        private static string GetRelativeUrl(Prod u)
        {
            switch (u)
            {
                case Prod.precheckorder:
                    return "http://ift.tt/2mf7xyh";
                case Prod.submitresubmit:
                    return "http://ift.tt/2mG5Bfy";
                case Prod.creditInquiry:
                    return "http://ift.tt/2mf9KtD";
                case Prod.createupdateorder:
                    return "http://ift.tt/2mGachR";
                case Prod.confirmorder:
                    return "http://ift.tt/2mf08Pk";
                case Prod.getorderstatus:
                    return "http://ift.tt/2mG8IUu";
                case Prod.cancelorder:
                    return "http://ift.tt/2mfdnzB";
                default:
                    // Handle bad URL, possibly throw
                    throw new Exception();
            }
        }

We use environment variables to store the Environment name and thats what dictates which API set to use.

Ideally, I would like to have a single method, I pass in my environment and api name and it will return the API Url.

Something like

GettexApiUrlBasedOnEnvironment("Dev", "precheckorder");

and response will be

"http://ift.tt/2mGaFQY"

Any ideas/suggestions will be much appreciated. TIA





Java. How to get non-nullable fields by reflection?

I try to get list of fields from class (hibernate entity). Like this:

Entity:

public class A {

    public static final Integer someValue = 1;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "a_id")
    private Integer id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "a_b_id", nullable = true)
    private List<B> b;

    @NotNull
    @Column(name = "a_c_id")
    private C c;

    .........................
}

Method for getting non-static fields:

public static List<Field> getNonStaticFields(Class clazz) {
    Field[] fields = clazz.getDeclaredFields();
    List<Field> fieldsList = new ArrayList<>();
    for (Field field : fields) {
        if (!Modifier.isStatic(field.getModifiers())) {
            fieldsList.add(field);
        }
    }

    return fieldsList;
}

But I need to get only non-nullable non-static fields. This means that I need to get fields with @NotNull annotation and @JoinColumn annotation with parameter "nullable = false".

Check for @NotNull is simple:

field.isAnnotationPresent(NotNull.class)

But I have no idea how can I check field for @JoinColumn with parameter. How can I do it? Can somebody help me?





How to convert Linq expression to Reflection (To make dynamic LINQ expression)

I have created three classes. Two classes Data and IntArrayEqualityComparer are below-

public class Data
    {   
        public Dictionary<int[], List<double>> s = new Dictionary<int[], List<double>>(new IntArrayEqualityComparer());        

        public Data()
        {
        }

        public Data(Dictionary<int[], List<double>> s)
        {
            this.s = s;
        }

        public Dictionary<int[], List<double>> S
        {
            get { return s; }
            set { s = value; }
        }
    }

 public class IntArrayEqualityComparer : IEqualityComparer<int[]>
    {
        public bool Equals(int[] x, int[] y)
        {
            if (x.Length != y.Length)
            {
                return false;
            }
            for (int i = 0; i < x.Length; i++)
            {
                if (x[i] != y[i])
                {
                    return false;
                }
            }
            return true;
        }

        public int GetHashCode(int[] obj)
        {
            int result = 17;
            for (int i = 0; i < obj.Length; i++)
            {
                unchecked
                {
                    result = result * 23 + obj[i];
                }
            }
            return result;
        }
    }

A third class named Expression is created in which I need to convert LINQ expression into Reflection -

public class Expresion
    {
        public void CreateExpression()
        {
            Expression<Func<Data, List<int>>> exp1 = null;
            //Below is the LINQ expression I want to convert
            exp1 = p2 => p2.s[new int[] { 14, 5 }].Select((item, index) => new { item, index }).Select(x => x.index).ToList();

            ParameterExpression p1 = Expression.Parameter(typeof(Data), "p");
            MethodInfo mInfo = typeof(List<double>).GetMethod("get_Item");
            MethodInfo mInfo1 = typeof(Dictionary<int, List<double>>).GetMethod("get_Item");
            MethodInfo mInfo2 = typeof(Dictionary<int[], List<double>>).GetMethod("get_Item");
            MethodInfo mInfo3 = typeof(List<int[]>).GetMethod("get_Item");

            MemberExpression s1 = Expression.Property(p1, "s");
            ParameterExpression index1 = Expression.Parameter(typeof(int), "index");
            ParameterExpression item1 = Expression.Parameter(typeof(double), "item");

            //Here I want to covert the "(item, index) => new { item, index }" part from LINQ expression into Reflection
        }
    }





Get action name as string for Attribute-parameter

I have some Action Attributes that allow parameters. This is how it looks like:

[DeleteActionCache(Action="GetTerms")]
public ActionResult AddTerm(string term){ }

public ActionResult GetTerms() {}

Now I want to get rid of the magic string "GetTerms" in my Attribute. So I would prefer something like: (Pseudocode, not working)

[DeleteActionCache(Action=this.GetTerms().GetType().Name)]

Having an additional Property inside my attribute-class and doing "Method2String"-Conversions inside my that class would be ok with me if this is needed to achieve what I want.

Info: I am not looking for a way the get the current method name (MethodBase.GetCurrentMethod)





org.reflections.ReflectionsException: Can't resolve member named #### for class [someClass].access

I encountered this exception when I was trying to call reflections.getMethodUsage(Method), using reflections library 0.9.10. JDK version: 1.8.0_121 64bit

Please investigate the relevant stacktrace below. Note that custom package names and class names are substituted:

Caused by: org.reflections.ReflectionsException: Can't resolve member named someClass.access$1300(someClass, anotherClass) #103
    at org.reflections.util.Utils.getMembersFromDescriptors(Utils.java:125)
    at org.reflections.Reflections.getMethodUsage(Reflections.java:574)
    at myCustomScanner.getCallers(myCustomScanner.java:145)
    at myCustomScanner.getBeanByMember(myCustomScanner.java:192)
    at myCustomScanner.getCallers(myCustomScanner.java:156)
    at myCustomScanner.getBeanByMember(myCustomScanner.java:192)
    at myCustomScanner.lambda$getServiceBeans$2(myCustomScanner.java:113)
    at java.lang.Iterable.forEach(Iterable.java:75)
    at myCustomScanner.getServiceBeans(myCustomScanner.java:111)
    at myCustomScanner.scan(myCustomScanner.java:87)
    at com.marvel.service.scanner.App.run(App.java:47)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:366)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:311)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:134)
    ... 22 more
Caused by: org.reflections.ReflectionsException: Can't resolve member named 1300 for class someClass.access
    at org.reflections.util.Utils.getMemberFromDescriptor(Utils.java:94)
    at org.reflections.util.Utils.getMembersFromDescriptors(Utils.java:123)
    ... 39 more

Progress I made so far: This weird member name '1300' and class name suffix '.access' seem to come from an anonymous class' method. I also found that the MemberUsageScanner is using javassist library to obtain this kind of info under the hood, but I failed to debug the process when MemberUsageScanner is scanning the members by setting a conditional breakpoint in Eclipse, the process seem to never reach that breakpoint and never proceed, hanging in the middle of nowhere.





How to get field name in Golang

Hi I'm looking for a function like this:

var fieldName string = getFieldName((&myStruct{}).AField)
log.Println(fieldName)//==> "AField"