vendredi 22 mai 2015

java compilation error when using reflection with templates

I have this code:

private <D extends Object> void foo(D d) throws IllegalAccessException, InstantiationException {
    d = d.getClass().newInstance(); // Compilation error: "Incompatible types: Required D, Found: Object"
}

Why do I get this error?

To my understanding, the compiler knows that d is D type (which extends Object)...?





Trying to make a generic Xml

I'm trying to make a method to create a soap envelope that has to be generic. Basically, what it does is receives a DTO file, reads a xml file with the soap and fills it with the values from the DTO. I have two DTO's for the moment but there will be more. I use Reflection to get the values from the DTO and fill the xml file. It works fine for one of the xml files, but I'm struggling to get it to work for the second one.

These are my XML files

It works fine with this one

<soap:Envelope xmlns:soap="http://ift.tt/sVJIaE">
  <soap:Body>
    <GetStreamsForEvent xmlns="...">
      <customerUID></customerUID>
      <eventId></eventId>
    </GetStreamsForEvent>
  </soap:Body>
</soap:Envelope>

Doesn't work with this one

<soap:Envelope xmlns:soap="http://ift.tt/sVJIaE">
  <soap:Body>
    <soap:Envelope xmlns:soap="http://ift.tt/sVJIaE">
  <soap:Body>
    <GenerateEventView xmlns="...">
      <igmStreamInput>
        <CustomerUID></CustomerUID>
        <UserIdentifier></UserIdentifier>
        <UserIPAddress></UserIPAddress>
        <EventID></EventID>
        <UniqueStreamName</UniqueStreamName>
        <RedirectURL></RedirectURL>
      </igmStreamInput>
    </GenerateEventView>
  </soap:Body>
</soap:Envelope>
  </soap:Body>
</soap:Envelope>

These are my DTO's

namespace TestServerIGMToken
{
    public class GetStreamsForEventDTO
    {
        /// <summary>
        /// 
        /// </summary>
        public string customerUID { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string eventId { get; set; }
    }
}


namespace TestServerIGMToken
{
    /// <summary>
    /// 
    /// </summary>
    public class GenerateEventViewDTO
    {
        ///// <summary>
        ///// 
        ///// </summary>
        //public string igmStreamInput { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string customerUID { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string UserIdentifier { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string UserIPAddress { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string EventID { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string UniqueStreamName { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string RedirectURL { get; set; }       
    }
}

These is my code

This function receives T streamsForEvent, shich can be one of the two DTO's. It creates a webrequest, fills the soap xml with values from the DTO, puts it in a stream and reads from it.

 /// <summary>
        /// 
        /// </summary>
        /// <param name="streamsForEvent"></param>
        /// <returns></returns>
        private string GetStreamsForEventProcess<T>(T streamsForEvent)
        {
            try
            {
                string getUri = GenericHelperMethods.GetResourceString(streamsForEvent, Resources.Uri);
                string getAction = GenericHelperMethods.GetResourceString(streamsForEvent, Resources.Action);

                HttpWebRequest getStreamsForEventWebRequest = CreateWebRequest(getUri, getAction);
                InsertSoapEnvelopeIntoWebRequest(GenericSoap.CreateSoapEnvelope(streamsForEvent), getStreamsForEventWebRequest);

                IAsyncResult asyncResult = getStreamsForEventWebRequest.BeginGetResponse(null, null);
                asyncResult.AsyncWaitHandle.WaitOne();

                using (WebResponse getStreamsForEventWebResponse = getStreamsForEventWebRequest.EndGetResponse(asyncResult))
                {
                    using (StreamReader getStreamsForEventStreamReader = new StreamReader(getStreamsForEventWebResponse.GetResponseStream()))
                    {
                        return getStreamsForEventStreamReader.ReadToEnd();
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

This method creates the webrequest

/// <summary>
        /// 
        /// </summary>
        /// <param name="getStreamsForEventUri"></param>
        /// <param name="getStreamsForEventAction"></param>
        /// <returns></returns>
        private static HttpWebRequest CreateWebRequest(string getStreamsForEventUri, string getStreamsForEventAction)
        {
            HttpWebRequest getStreamsForEventWebRequest = WebRequest.Create(getStreamsForEventUri) as HttpWebRequest;
            getStreamsForEventWebRequest.Headers.Add("SOAPAction", getStreamsForEventAction);
            getStreamsForEventWebRequest.ContentType = "text/xml;charset=\"utf-8\"";
            getStreamsForEventWebRequest.Accept = "text/xml";
            getStreamsForEventWebRequest.Method = "POST";

            return getStreamsForEventWebRequest;
        }

This method inserts soap envelop into the stream

/// <summary>
        /// 
        /// </summary>
        /// <param name="getStreamsForEventSoapEnvelope"></param>
        /// <param name="getStreamsForEventWebRequest"></param>
        private static void InsertSoapEnvelopeIntoWebRequest(XmlDocument getStreamsForEventSoapEnvelope, HttpWebRequest getStreamsForEventWebRequest)
        {
            using (Stream stream = getStreamsForEventWebRequest.GetRequestStream())
            {
                getStreamsForEventSoapEnvelope.Save(stream);
            }
        }

This method creates the soap envelope

/// <summary>
        /// 
        /// </summary>
        /// <param name="streamsForEvent"></param>
        /// <returns></returns>
        private static XmlDocument CreateSoapEnvelopeProcess<T>(T streamsForEvent)
        {
            XmlDocument soapEnvelop = new XmlDocument();

            soapEnvelop.LoadXml(File.ReadAllText(string.Format(@"C:\{0}.xml", streamsForEvent.GetType().Name.Replace("DTO", ""))));

            return FillSoapEnvelop(soapEnvelop, streamsForEvent);
        }

This method does the actuall filling of the soap envelop. I used reflection to get the name of each property of the DTO file, then I do a GetElementsByTagName with the property's name and then I fill it with the property's value.

/// <summary>
    /// 
    /// </summary>
    /// <param name="getStreamsForEventSoapEnvelope"></param>
    /// <param name="streamsForEvent"></param>
    /// <returns></returns>
    private static XmlDocument FillSoapEnvelop<T>(XmlDocument getStreamsForEventSoapEnvelope, T streamsForEvent) 
    {
        foreach (PropertyInfo property in typeof (T).GetProperties())
        {
            getStreamsForEventSoapEnvelope.GetElementsByTagName(property.Name).Item(0).InnerText = GenericHelperMethods.GetPropertyValue(streamsForEvent, property);  
        }

        return getStreamsForEventSoapEnvelope;
    }

This method gets the value of the DTO's properties

/// <summary>
        /// 
        /// </summary>
        /// <param name="streamsForEvent"></param>
        /// <param name="property"></param>
        /// <returns></returns>
        public static string GetPropertyValue<T>(T streamsForEvent, PropertyInfo property)
        {
            return streamsForEvent.GetType().GetProperty(property.Name).GetValue(streamsForEvent, null).ToString();
        }

The problem occurrs at

private static XmlDocument FillSoapEnvelop<T>(XmlDocument getStreamsForEventSoapEnvelope, T streamsForEvent) 

The way I'm reading the xml must have some problem, because it works fine with with

 <soap:Envelope xmlns:soap="http://ift.tt/sVJIaE">
      <soap:Body>
        <GetStreamsForEvent xmlns="...">
          <customerUID></customerUID>
          <eventId></eventId>
        </GetStreamsForEvent>
      </soap:Body>
    </soap:Envelope>

but not with

<soap:Envelope xmlns:soap="http://ift.tt/sVJIaE">
  <soap:Body>
    <soap:Envelope xmlns:soap="http://ift.tt/sVJIaE">
  <soap:Body>
    <GenerateEventView xmlns="...">
      <igmStreamInput>
        <CustomerUID></CustomerUID>
...
        <RedirectURL></RedirectURL>
      </igmStreamInput>
    </GenerateEventView>
  </soap:Body>
</soap:Envelope>
  </soap:Body>
</soap:Envelope>

Any ideas? Tks in advance.





Identify test classes dynamically

I required a solution to identify test classes from a jar file and execute them .That is my web application accept a jar file as input and identify test classes inside the jar and execute them and show the result.





Java Reflection. Access the value of a field

I am trying to complete a program with Java Reflection. I have a problem with this part. I can not get the value of the field I am looking for.

Field [] fx = ArrayUtils.addAll(c.getDeclaredFields(),c.getFields());
for (int j = 0; i < fx.length; j++){
    System.out.println(fx[j].toString());
    if( fx[j].isAnnotationPresent(Searchable.class)){
        Searchable ann = fx[j].getAnnotation(Searchable.class);
        System.out.println(ann.field() + " " + fx[j].getGenericType());
        if (ann.field().equals(field)){
    System.out.println ("Found it!");
    try {
        fx[j].setAccessible(true);
        System.out.println((String)fx[j].get(c));
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    break;
        }
    }
}

With this code I get this message:

java.lang.IllegalArgumentException: Can not set java.lang.String field store.model.Book.publisher to java.lang.Class

Any idea how I can do it? Thanks a lot in advance.





jeudi 21 mai 2015

Setting the Value of a Field Without Knowing The Type Java Reflection

I have been working on this problem for more than 12 hours without success so if anyone can help with this or provide a different solution I will be eternally grateful. The main problem iv'e been running into is changing fields with the class inheritance structure which i will attempt to explain:

The "craftPlayer" variable is an instance of CraftPlayer which is a child class of CraftEntity. The CraftEntity class contains a Entity object which has the variable "uniqueID". So Basically all i'm trying to do is change that uniqueID variable for "craftPlayer". I don't have access to any of the classes so i'm using reflection. The problem i'm running into currently is trying to change the Entity variable which is inside "craftPlayer" the but i can't figure out a way to get the instance of that class as the "entity" variable is really an instance of EntityPlayer and not Entity

I realize this was very poorly explained so ask as many clarifying questions as you want. Any help would be much appreciated.

        CraftEntity craftPlayer = (CraftEntity) player;
        @SuppressWarnings("unchecked")
        Class<CraftEntity> craftEntityClass = getCraftEntityClass((Class<CraftEntity>) craftPlayer.getClass());

        for (Field field : craftEntityClass.getDeclaredFields()) {
            field.setAccessible(true);
            if (field.getName().equals("entity")) {
                Object object = field.get(craftPlayer);
                Entity entity = (Entity) object;
                entity.uniqueID = new UUID(0L, 0L);
                field.set(entity, entity); //"entity" is really an instance of EntityPlayer which is a subclass of Entity so i am unable to change the field because upclassing does not seem to work
                break;
            }
        }





Check if this pointer was accessed in an instance method

I am trying to detect if the this pointer was accessed in a dot net instance method. Could be a call to an instance method, access to a member variable etc.

Currently digging into Reflection: MethodBase.GetMethodBody if I can figure it out from the IL.





Method Interception to get property name

I am looking for a utility class or library that gives me the name of the property in a type-safe way. I have something similar like the following in mind:

PropertyDescriptor descriptor = property(on(Foo.class).getBar());

assertThat(descriptor.getName()).isEqualTo("bar")

To have such a convenience method implemented properly requires IMHO quiet a lot of work. As the handling of final classes and the like can be extremely complex (see mockito, easymock etc.)