This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I am Passing a string to a setter method
PostPublication postPublication = new PostPublication();
/*
* Class MessageCont = Class.forName(messageContext
* .getProperty("MessageContent").toString());
*/
postPublication
.setMessageContent((MessageContent_type0) messageContext
.getProperty("MessageContent"));
The Setter method at PostPublication Class is
public void setMessageContent(
org.openoandm.www.xml.isbm.MessageContent_type0 param) {
this.localMessageContent = param;
}
Declaration of localMessageContent is
protected org.openoandm.www.xml.isbm.MessageContent_type0 localMessageContent;
MessageContent_type0 class code
/**
* MessageContent_type0.java
*
* This file was auto-generated from WSDL
* by the Apache Axis2 version: 1.6.2 Built on : Apr 17, 2012 (05:34:40 IST)
*/
package org.openoandm.www.xml.isbm;
/**
* MessageContent_type0 bean class
*/
#SuppressWarnings({"unchecked","unused"})
public class MessageContent_type0
implements org.apache.axis2.databinding.ADBBean{
/* This type was generated from the piece of schema that had
name = MessageContent_type0
Namespace URI = http://www.openoandm.org/xml/ISBM/
Namespace Prefix = ns1
*/
/**
* field for ExtraElement
*/
protected org.apache.axiom.om.OMElement localExtraElement ;
/**
* Auto generated getter method
* #return org.apache.axiom.om.OMElement
*/
public org.apache.axiom.om.OMElement getExtraElement(){
return localExtraElement;
}
/**
* Auto generated setter method
* #param param ExtraElement
*/
public void setExtraElement(org.apache.axiom.om.OMElement param){
this.localExtraElement=param;
}
/**
*
* #param parentQName
* #param factory
* #return org.apache.axiom.om.OMElement
*/
public org.apache.axiom.om.OMElement getOMElement (
final javax.xml.namespace.QName parentQName,
final org.apache.axiom.om.OMFactory factory) throws org.apache.axis2.databinding.ADBException{
org.apache.axiom.om.OMDataSource dataSource =
new org.apache.axis2.databinding.ADBDataSource(this,parentQName);
return factory.createOMElement(dataSource,parentQName);
}
public void serialize(final javax.xml.namespace.QName parentQName,
javax.xml.stream.XMLStreamWriter xmlWriter)
throws javax.xml.stream.XMLStreamException, org.apache.axis2.databinding.ADBException{
serialize(parentQName,xmlWriter,false);
}
public void serialize(final javax.xml.namespace.QName parentQName,
javax.xml.stream.XMLStreamWriter xmlWriter,
boolean serializeType)
throws javax.xml.stream.XMLStreamException, org.apache.axis2.databinding.ADBException{
java.lang.String prefix = null;
java.lang.String namespace = null;
prefix = parentQName.getPrefix();
namespace = parentQName.getNamespaceURI();
writeStartElement(prefix, namespace, parentQName.getLocalPart(), xmlWriter);
if (serializeType){
java.lang.String namespacePrefix = registerPrefix(xmlWriter,"http://www.openoandm.org/xml/ISBM/");
if ((namespacePrefix != null) && (namespacePrefix.trim().length() > 0)){
writeAttribute("xsi","http://www.w3.org/2001/XMLSchema-instance","type",
namespacePrefix+":MessageContent_type0",
xmlWriter);
} else {
writeAttribute("xsi","http://www.w3.org/2001/XMLSchema-instance","type",
"MessageContent_type0",
xmlWriter);
}
}
if (localExtraElement != null) {
localExtraElement.serialize(xmlWriter);
} else {
throw new org.apache.axis2.databinding.ADBException("extraElement cannot be null!!");
}
xmlWriter.writeEndElement();
}
private static java.lang.String generatePrefix(java.lang.String namespace) {
if(namespace.equals("http://www.openoandm.org/xml/ISBM/")){
return "ns1";
}
return org.apache.axis2.databinding.utils.BeanUtil.getUniquePrefix();
}
/**
* Utility method to write an element start tag.
*/
private void writeStartElement(java.lang.String prefix, java.lang.String namespace, java.lang.String localPart,
javax.xml.stream.XMLStreamWriter xmlWriter) throws javax.xml.stream.XMLStreamException {
java.lang.String writerPrefix = xmlWriter.getPrefix(namespace);
if (writerPrefix != null) {
xmlWriter.writeStartElement(namespace, localPart);
} else {
if (namespace.length() == 0) {
prefix = "";
} else if (prefix == null) {
prefix = generatePrefix(namespace);
}
xmlWriter.writeStartElement(prefix, localPart, namespace);
xmlWriter.writeNamespace(prefix, namespace);
xmlWriter.setPrefix(prefix, namespace);
}
}
/**
* Util method to write an attribute with the ns prefix
*/
private void writeAttribute(java.lang.String prefix,java.lang.String namespace,java.lang.String attName,
java.lang.String attValue,javax.xml.stream.XMLStreamWriter xmlWriter) throws javax.xml.stream.XMLStreamException{
if (xmlWriter.getPrefix(namespace) == null) {
xmlWriter.writeNamespace(prefix, namespace);
xmlWriter.setPrefix(prefix, namespace);
}
xmlWriter.writeAttribute(namespace,attName,attValue);
}
/**
* Util method to write an attribute without the ns prefix
*/
private void writeAttribute(java.lang.String namespace,java.lang.String attName,
java.lang.String attValue,javax.xml.stream.XMLStreamWriter xmlWriter) throws javax.xml.stream.XMLStreamException{
if (namespace.equals("")) {
xmlWriter.writeAttribute(attName,attValue);
} else {
registerPrefix(xmlWriter, namespace);
xmlWriter.writeAttribute(namespace,attName,attValue);
}
}
/**
* Util method to write an attribute without the ns prefix
*/
private void writeQNameAttribute(java.lang.String namespace, java.lang.String attName,
javax.xml.namespace.QName qname, javax.xml.stream.XMLStreamWriter xmlWriter) throws javax.xml.stream.XMLStreamException {
java.lang.String attributeNamespace = qname.getNamespaceURI();
java.lang.String attributePrefix = xmlWriter.getPrefix(attributeNamespace);
if (attributePrefix == null) {
attributePrefix = registerPrefix(xmlWriter, attributeNamespace);
}
java.lang.String attributeValue;
if (attributePrefix.trim().length() > 0) {
attributeValue = attributePrefix + ":" + qname.getLocalPart();
} else {
attributeValue = qname.getLocalPart();
}
if (namespace.equals("")) {
xmlWriter.writeAttribute(attName, attributeValue);
} else {
registerPrefix(xmlWriter, namespace);
xmlWriter.writeAttribute(namespace, attName, attributeValue);
}
}
/**
* method to handle Qnames
*/
private void writeQName(javax.xml.namespace.QName qname,
javax.xml.stream.XMLStreamWriter xmlWriter) throws javax.xml.stream.XMLStreamException {
java.lang.String namespaceURI = qname.getNamespaceURI();
if (namespaceURI != null) {
java.lang.String prefix = xmlWriter.getPrefix(namespaceURI);
if (prefix == null) {
prefix = generatePrefix(namespaceURI);
xmlWriter.writeNamespace(prefix, namespaceURI);
xmlWriter.setPrefix(prefix,namespaceURI);
}
if (prefix.trim().length() > 0){
xmlWriter.writeCharacters(prefix + ":" + org.apache.axis2.databinding.utils.ConverterUtil.convertToString(qname));
} else {
// i.e this is the default namespace
xmlWriter.writeCharacters(org.apache.axis2.databinding.utils.ConverterUtil.convertToString(qname));
}
} else {
xmlWriter.writeCharacters(org.apache.axis2.databinding.utils.ConverterUtil.convertToString(qname));
}
}
private void writeQNames(javax.xml.namespace.QName[] qnames,
javax.xml.stream.XMLStreamWriter xmlWriter) throws javax.xml.stream.XMLStreamException {
if (qnames != null) {
// we have to store this data until last moment since it is not possible to write any
// namespace data after writing the charactor data
java.lang.StringBuffer stringToWrite = new java.lang.StringBuffer();
java.lang.String namespaceURI = null;
java.lang.String prefix = null;
for (int i = 0; i < qnames.length; i++) {
if (i > 0) {
stringToWrite.append(" ");
}
namespaceURI = qnames[i].getNamespaceURI();
if (namespaceURI != null) {
prefix = xmlWriter.getPrefix(namespaceURI);
if ((prefix == null) || (prefix.length() == 0)) {
prefix = generatePrefix(namespaceURI);
xmlWriter.writeNamespace(prefix, namespaceURI);
xmlWriter.setPrefix(prefix,namespaceURI);
}
if (prefix.trim().length() > 0){
stringToWrite.append(prefix).append(":").append(org.apache.axis2.databinding.utils.ConverterUtil.convertToString(qnames[i]));
} else {
stringToWrite.append(org.apache.axis2.databinding.utils.ConverterUtil.convertToString(qnames[i]));
}
} else {
stringToWrite.append(org.apache.axis2.databinding.utils.ConverterUtil.convertToString(qnames[i]));
}
}
xmlWriter.writeCharacters(stringToWrite.toString());
}
}
/**
* Register a namespace prefix
*/
private java.lang.String registerPrefix(javax.xml.stream.XMLStreamWriter xmlWriter, java.lang.String namespace) throws javax.xml.stream.XMLStreamException {
java.lang.String prefix = xmlWriter.getPrefix(namespace);
if (prefix == null) {
prefix = generatePrefix(namespace);
javax.xml.namespace.NamespaceContext nsContext = xmlWriter.getNamespaceContext();
while (true) {
java.lang.String uri = nsContext.getNamespaceURI(prefix);
if (uri == null || uri.length() == 0) {
break;
}
prefix = org.apache.axis2.databinding.utils.BeanUtil.getUniquePrefix();
}
xmlWriter.writeNamespace(prefix, namespace);
xmlWriter.setPrefix(prefix, namespace);
}
return prefix;
}
/**
* databinding method to get an XML representation of this object
*
*/
public javax.xml.stream.XMLStreamReader getPullParser(javax.xml.namespace.QName qName)
throws org.apache.axis2.databinding.ADBException{
java.util.ArrayList elementList = new java.util.ArrayList();
java.util.ArrayList attribList = new java.util.ArrayList();
if (localExtraElement != null){
elementList.add(org.apache.axis2.databinding.utils.Constants.OM_ELEMENT_KEY);
elementList.add(localExtraElement);
} else {
throw new org.apache.axis2.databinding.ADBException("extraElement cannot be null!!");
}
return new org.apache.axis2.databinding.utils.reader.ADBXMLStreamReaderImpl(qName, elementList.toArray(), attribList.toArray());
}
/**
* Factory class that keeps the parse method
*/
public static class Factory{
/**
* static method to create the object
* Precondition: If this object is an element, the current or next start element starts this object and any intervening reader events are ignorable
* If this object is not an element, it is a complex type and the reader is at the event just after the outer start element
* Postcondition: If this object is an element, the reader is positioned at its end element
* If this object is a complex type, the reader is positioned at the end element of its outer element
*/
public static MessageContent_type0 parse(javax.xml.stream.XMLStreamReader reader) throws java.lang.Exception{
MessageContent_type0 object =
new MessageContent_type0();
int event;
java.lang.String nillableValue = null;
java.lang.String prefix ="";
java.lang.String namespaceuri ="";
try {
while (!reader.isStartElement() && !reader.isEndElement())
reader.next();
if (reader.getAttributeValue("http://www.w3.org/2001/XMLSchema-instance","type")!=null){
java.lang.String fullTypeName = reader.getAttributeValue("http://www.w3.org/2001/XMLSchema-instance",
"type");
if (fullTypeName!=null){
java.lang.String nsPrefix = null;
if (fullTypeName.indexOf(":") > -1){
nsPrefix = fullTypeName.substring(0,fullTypeName.indexOf(":"));
}
nsPrefix = nsPrefix==null?"":nsPrefix;
java.lang.String type = fullTypeName.substring(fullTypeName.indexOf(":")+1);
if (!"MessageContent_type0".equals(type)){
//find namespace for the prefix
java.lang.String nsUri = reader.getNamespaceContext().getNamespaceURI(nsPrefix);
return (MessageContent_type0)org.openoandm.www.xml.isbm.ExtensionMapper.getTypeObject(
nsUri,type,reader);
}
}
}
// Note all attributes that were handled. Used to differ normal attributes
// from anyAttributes.
java.util.Vector handledAttributes = new java.util.Vector();
reader.next();
while (!reader.isStartElement() && !reader.isEndElement()) reader.next();
if (reader.isStartElement()){
//use the QName from the parser as the name for the builder
javax.xml.namespace.QName startQname1 = reader.getName();
// We need to wrap the reader so that it produces a fake START_DOCUMENT event
// this is needed by the builder classes
org.apache.axis2.databinding.utils.NamedStaxOMBuilder builder1 =
new org.apache.axis2.databinding.utils.NamedStaxOMBuilder(
new org.apache.axis2.util.StreamWrapper(reader),startQname1);
object.setExtraElement(builder1.getOMElement());
reader.next();
} // End of if for expected property start element
else{
// A start element we are not expecting indicates an invalid parameter was passed
throw new org.apache.axis2.databinding.ADBException("Unexpected subelement " + reader.getName());
}
while (!reader.isStartElement() && !reader.isEndElement())
reader.next();
if (reader.isStartElement())
// A start element we are not expecting indicates a trailing invalid property
throw new org.apache.axis2.databinding.ADBException("Unexpected subelement " + reader.getName());
} catch (javax.xml.stream.XMLStreamException e) {
throw new java.lang.Exception(e);
}
return object;
}
}//end of factory class
}
When i am passing data to set the setter method it throws exception as
java.lang.String cannot be cast to org.openoandm.www.xml.isbm.MessageContent_type0
How can i set the setter method by passing string in it?Thanks in advance
You need to turn your String into a MessageContent_type0, a simple cast won't do.
No idea what this class is, but maybe there is something like
new MessageContent_type0(myString);
it is not allowed in java. you can either upcast or downcast any object in a inheritance-hierarchy. But can not cast to anything out of the inheritance-hierarchy.
in your case, in type of localMessageContent there must be some constructor with string param or method like setMessage(string)
Related
I have Escrypt Smart Card to sign data bytes and get signature and certificate for it.
I have java tool to do it and everything was fine until Java 8. Now application migrated to Java 11. And problem start from here.
SunPKCS11.jar/ library is not a part of Java 11, hence application breaks.
I tried with different solution available over internet and oracle release notes, it suggest to use java.security package for cryptographic operation.
I am not able to switch from Java 8 to java 11, any support would be really useful.
Edit-1: Minimum usable code
Signature calculator is used to parse signature
It is written with Java 8 & SunPKCS11.jar want to migrate it to Java 11
'''
import java.io.IOException;
import java.util.Scanner;
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
import sun.security.pkcs11.wrapper.CK_ATTRIBUTE;
import sun.security.pkcs11.wrapper.CK_MECHANISM;
import sun.security.pkcs11.wrapper.CK_RSA_PKCS_PSS_PARAMS;
import sun.security.pkcs11.wrapper.PKCS11;
import sun.security.pkcs11.wrapper.PKCS11Constants;
import sun.security.pkcs11.wrapper.PKCS11Exception;
public class Application {
public static void main(String[] args) {
try {
// PKCS11 middleware (UBK PKI) path
String libraryPath = "";
OpenScPkcs11 openScPkcs11 = new OpenScPkcs11(libraryPath);
openScPkcs11.login("", "");
byte[] hash = null;
String keypath = null;
String oid = null;
String authbits = null;
openScPkcs11.calcSign(hash, keypath, oid, authbits);
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class OpenScPkcs11 {
private static HexBinaryAdapter hexBinaryAdapter = new HexBinaryAdapter();
private int slotId = 0x3;
private String libraryPath;
private PKCS11 pkcs11Instance;
private String signatureAlgo = "RSA";
private long session = -1;
private boolean isLoginDone = false;
private SignatureMechanism.Algorithms algorithm = SignatureMechanism.Algorithms.SHA256;
public OpenScPkcs11(String libraryPath) throws IOException, PKCS11Exception {
this.libraryPath = libraryPath;
initializeMiddleware();
}
public void calcSign(byte[] hash, String keyPath, String userOid, String authbits) throws Exception {
byte[] signature = new byte[512];
if (this.pkcs11Instance != null) {
if (this.session < 0) {
this.openSession();
}
if (!this.isLoginDone) {
this.login("", "");
}
Mechanism mechanism = SignatureMechanism.getMechanism(this.algorithm);
CK_ATTRIBUTE[] pTemplate = new CK_ATTRIBUTE[3];
pTemplate[0] = new CK_ATTRIBUTE(PKCS11Constants.CKA_CLASS, PKCS11Constants.CKO_PRIVATE_KEY);
pTemplate[1] = new CK_ATTRIBUTE(PKCS11Constants.CKA_VENDOR_DEFINED + 1, keyPath);
pTemplate[2] = new CK_ATTRIBUTE(PKCS11Constants.CKA_VENDOR_DEFINED + 2, authbits);
// define the attibutes for certificate
CK_ATTRIBUTE[] certAttribute = new CK_ATTRIBUTE[1];
certAttribute[0] = new CK_ATTRIBUTE(PKCS11Constants.CKA_VENDOR_DEFINED + 3);
long[] c_FindObjects = null;
this.pkcs11Instance.C_FindObjectsInit(this.session, pTemplate);
c_FindObjects = this.pkcs11Instance.C_FindObjects(this.session, 32);
this.pkcs11Instance.C_FindObjectsFinal(this.session);
CK_MECHANISM pMechanism = null;
// RSA Algorithm
String signatureAlgorithmType = this.getSignatureAlgorithmType();
if (signatureAlgorithmType.equalsIgnoreCase("RSA")) {
pMechanism = new CK_MECHANISM(mechanism.getId());
CK_RSA_PKCS_PSS_PARAMS ck_RSA_PKCS_PSS_PARAMS =
new CK_RSA_PKCS_PSS_PARAMS(this.algorithm.name(), "MGF1", this.algorithm.name(), (int) mechanism.getsLen());
pMechanism.pParameter = ck_RSA_PKCS_PSS_PARAMS;
}
else if (signatureAlgorithmType.equalsIgnoreCase("ECDSA")) { // ECDSA Algorithm
pMechanism = new CK_MECHANISM(PKCS11Constants.CKM_ECDSA);
}
else {
throw new Exception("Signature algorithm " + signatureAlgorithmType + " is not supported");
}
if ((c_FindObjects != null) && (c_FindObjects.length > 0)) {
long c_FindObjectFound = c_FindObjects[0];
boolean objFound = false;
for (long c_FindObject : c_FindObjects) {
this.pkcs11Instance.C_GetAttributeValue(this.session, c_FindObject, certAttribute);
// Binary certificate as byte array
byte[] certificateBytes = certAttribute[0].getByteArray();
if ((userOid != null) && !userOid.isEmpty()) {
// Match certificate with userOid, if matches (Certificate parser used)
if (parseOidInfo(certificateBytes, userOid)) {
c_FindObjectFound = c_FindObject;
objFound = true;
break;
}
}
}
if (objFound) {
System.out.println("Signature found for given OID configuration.");
}
else {
this.pkcs11Instance.C_GetAttributeValue(this.session, c_FindObjectFound, certAttribute);
CertificateParser certificateParser = new CertificateParser(certAttribute[0].getByteArray());
}
this.pkcs11Instance.C_SignInit(this.session, pMechanism, c_FindObjectFound);
this.pkcs11Instance.C_SignUpdate(this.session, 0, hash, 0, (int) mechanism.getsLen());
signature = this.pkcs11Instance.C_SignFinal(this.session, mechanism.getSignFinalArgument());
}
else {
String errorMessage = "Unable to find keys.";
throw new Exception(errorMessage);
}
}
else {
throw new Exception("Initialize middleware first.");
}
}
/**
* #return
*/
private String getSignatureAlgorithmType() {
return this.signatureAlgo;
}
public void login(String userName, String password) throws Exception {
if (this.pkcs11Instance != null) {
openSession();
String pwd = password;
if (pwd == null || pwd.trim().isEmpty()) {
Scanner sc = new Scanner(System.in);
pwd = sc.next();
sc.close();
}
this.pkcs11Instance.C_Login(this.session, PKCS11Constants.CKU_USER, pwd.toCharArray());
this.isLoginDone = true;
}
else {
throw new Exception("Initialize middleware first.");
}
}
public void logout() throws PKCS11Exception {
if (this.pkcs11Instance != null) {
this.pkcs11Instance.C_Logout(this.session);
}
}
public void openSession() throws Exception {
if (this.pkcs11Instance != null) {
if (this.session < 0) {
long[] c_GetSlotList = this.pkcs11Instance.C_GetSlotList(true);
if ((c_GetSlotList != null) && (c_GetSlotList.length > 0)) {
for (long element : c_GetSlotList) {
if (element == this.slotId) {
this.session =
this.pkcs11Instance.C_OpenSession(this.slotId, PKCS11Constants.CKF_SERIAL_SESSION, null, null);
break;
}
}
}
}
}
else {
throw new Exception("Initialize middleware first.");
}
}
public void closeSession() throws PKCS11Exception {
if ((this.pkcs11Instance != null) && (this.session >= 0)) {
this.pkcs11Instance.C_CloseSession(this.session);
this.session = -1;
}
}
public void initializeMiddleware(String libraryPath1) throws IOException, PKCS11Exception {
this.pkcs11Instance = PKCS11.getInstance(libraryPath1, "C_GetFunctionList", null, false);
this.libraryPath = libraryPath1;
}
public void initializeMiddleware() throws IOException, PKCS11Exception {
this.pkcs11Instance = PKCS11.getInstance(this.libraryPath, "C_GetFunctionList", null, false);
}
public static String getString(final byte[] data) {
if ((data != null) && (data.length > 0)) {
return hexBinaryAdapter.marshal(data);
}
return null;
}
}
class SignatureMechanism {
public static enum Algorithms {
SHA256(0x250),
/**
* Hash calculation Algorithm
*/
RIPEMD160(0x240),
/**
* Hash calculation Algorithm
*/
RIPEMD160_1(0x0),
/**
* Secure Hash Algorithm 512 for hash Calculation
*/
SHA512(0x251);
private int value = 0;
private Algorithms(final int algorithmValue) {
this.value = algorithmValue;
}
/**
* #return the hash value
*/
public int getValue() {
return this.value;
}
}
/**
* #param algorithm : Algorithm used for hash calculation
* #return signature mechanism
*/
public static Mechanism getMechanism(final Algorithms algorithm) {
Mechanism mechanism = new Mechanism();
if (algorithm == Algorithms.SHA256) {
mechanism.setHashAlg(PKCS11Constants.CKM_SHA256);
mechanism.setMgf(PKCS11Constants.CKG_MGF1_SHA1 + 1);
mechanism.setsLen(32);
mechanism.setSignFinalArgument(512);
} // TODO Verify with ETAS Middleware team
else if (algorithm == Algorithms.SHA512) {
mechanism.setHashAlg(PKCS11Constants.CKM_SHA512);
mechanism.setMgf(PKCS11Constants.CKG_MGF1_SHA1 + 1);
mechanism.setsLen(64);
mechanism.setSignFinalArgument(1024);
}
else if (algorithm == Algorithms.RIPEMD160) {
mechanism.setHashAlg(PKCS11Constants.CKM_RIPEMD160);
mechanism.setMgf(0x80000001); // hard coded becuase it is defined by escrypt and not present in PKCS11
mechanism.setsLen(20);
}
else if (algorithm == Algorithms.RIPEMD160_1) {
mechanism.setId(PKCS11Constants.CKM_RIPEMD160_RSA_PKCS);
}
return mechanism;
}
}
class Mechanism{
private long hashAlg;
private long mgf;
private long sLen;
private long ulMaxObjectCount = 32;
private int signFinalArgument = 128;
private long id = PKCS11Constants.CKM_RSA_PKCS_PSS;
/**
* #return the hashAlg
*/
public long getHashAlg() {
return hashAlg;
}
/**
* #param hashAlg the hashAlg to set
*/
public void setHashAlg(long hashAlg) {
this.hashAlg = hashAlg;
}
/**
* #return the mgf
*/
public long getMgf() {
return mgf;
}
/**
* #param mgf the mgf to set
*/
public void setMgf(long mgf) {
this.mgf = mgf;
}
/**
* #return the sLen
*/
public long getsLen() {
return sLen;
}
/**
* #param sLen the sLen to set
*/
public void setsLen(long sLen) {
this.sLen = sLen;
}
/**
* #return the ulMaxObjectCount
*/
public long getUlMaxObjectCount() {
return ulMaxObjectCount;
}
/**
* #param ulMaxObjectCount the ulMaxObjectCount to set
*/
public void setUlMaxObjectCount(long ulMaxObjectCount) {
this.ulMaxObjectCount = ulMaxObjectCount;
}
/**
* #return the signFinalArgument
*/
public int getSignFinalArgument() {
return signFinalArgument;
}
/**
* #param signFinalArgument the signFinalArgument to set
*/
public void setSignFinalArgument(int signFinalArgument) {
this.signFinalArgument = signFinalArgument;
}
/**
* #return the id
*/
public long getId() {
return id;
}
/**
* #param id the id to set
*/
public void setId(long id) {
this.id = id;
}
}
'''
Thank You!
Java 9 up no longer puts the standard-library in jar files (rt.jar, etc) but they are still there. Your problem is probably (though I didn't read through all the code and certainly can't test without your hardware) that Java 9 up also introduces modules. Much as in Java forever your code can reference another class or interface (or static member therof) by its simple name only if you import it or it is in the same package as your code (if any) or the special package java.lang, now in 9 up you can only access a package if it is in the same module as your code or the special java.base module or your module and/or the other module explicitly allow the access; the explicit specification closet to older Java is an 'open'.
Thus the quick solution is to add to your java command (explicitly or via _JAVA_OPTS or equivalent) --add-opens jdk.crypto.cryptoki/sun.security.pkcs11.*=ALL-UNNAMED -- this should produce substantially the same result as running on 8 (or lower).
The official solution is to put your code in a module -- either by itself or with other related code -- that requires the (or each) needed module, given it exports the needed parts, which I haven't checked for yours. However, since your code apparently isn't even in a package yet, putting it in a module will be some work.
I'm working on an Android Library and I need to remove the play services dependencies to be added by the developer who used my library. I need user location last location so I need to use reflection because the location library will not be included directly in my library.
But how to create the googleApiClient from the builder via reflection ?
Digging into reflection and Play Services produce the following script. It contain the code for getting AdvertisingId and the location.
Gist also available.
private void getLocation(Context context) {
Log.d(LOG_TAG, "getLocation");
if (context.getPackageManager().checkPermission(
Manifest.permission.ACCESS_FINE_LOCATION, context.getPackageName()) == PackageManager.PERMISSION_GRANTED ||
context.getPackageManager().checkPermission(
Manifest.permission.ACCESS_COARSE_LOCATION, context.getPackageName()) == PackageManager.PERMISSION_GRANTED) {
try {
Class<?> apiClientBuilderClass = Class.forName("com.google.android.gms.common.api.GoogleApiClient$Builder");
Class<?> connectionCallbackClass = Class.forName("com.google.android.gms.common.api.GoogleApiClient$ConnectionCallbacks");
Class<?> connectionFailedCallbackClass = Class.forName("com.google.android.gms.common.api.GoogleApiClient$OnConnectionFailedListener");
Class<?> locationServicesClass = Class.forName("com.google.android.gms.location.LocationServices");
Constructor<?> constructorApiBuilder = apiClientBuilderClass.getConstructor(Context.class);
Object objectApiBuilder = constructorApiBuilder.newInstance(mContext);
// Create intance of listener ConnectionCallbacks
Class<?>[] connectionClassArray = new Class<?>[1];
connectionClassArray[0] = connectionCallbackClass;
sGoogleApiClientListener = Proxy.newProxyInstance(
connectionCallbackClass.getClassLoader(), connectionClassArray, new GoogleApiClientListener());
Method connectionMethodObject = apiClientBuilderClass.getMethod("addConnectionCallbacks", connectionCallbackClass);
connectionMethodObject.invoke(objectApiBuilder, sGoogleApiClientListener);
// Create instance of OnConnectionFailedListener listener
Class<?>[] connectionFailedClassArray = new Class<?>[1];
connectionFailedClassArray[0] = connectionFailedCallbackClass;
sGoogleApiClientFailedListener = Proxy.newProxyInstance(
connectionFailedCallbackClass.getClassLoader(), connectionFailedClassArray, new GoogleApiClientFailedListener());
Method connectionFailedMethodObject = apiClientBuilderClass.getMethod("addOnConnectionFailedListener", connectionFailedCallbackClass);
connectionFailedMethodObject.invoke(objectApiBuilder, sGoogleApiClientFailedListener);
// Add Api
Method addApiMethod = apiClientBuilderClass.getMethod("addApi", Class.forName("com.google.android.gms.common.api.Api"));
addApiMethod.invoke(objectApiBuilder, locationServicesClass.getField("API").get(null));
// Build
Method buildMethod = apiClientBuilderClass.getMethod("build");
sGoogleApiClient = buildMethod.invoke(objectApiBuilder);
// Connect
for (Method method : sGoogleApiClient.getClass().getMethods()) {
if (!"connect".equals(method.getName())) {
continue;
}
method.invoke(sGoogleApiClient);
break;
}
} catch (Exception e) {
// Location is not essential, so it's not an error
Log.v(LOG_TAG, "Exception on getLocation " + Log.getStackTraceString(e));
}
} else {
sLocation = "";
}
}
// GoogleApiClient for Locationsucceded
public void onConnected() {
Location lastLocation = null;
try {
// FusedLocationApi is a field of LocationServices, getting it.
Class<?> locationServicesClass = Class.forName("com.google.android.gms.location.LocationServices");
Class<?> locationProviderClass = Class.forName("com.google.android.gms.location.FusedLocationProviderApi");
for (Method method : locationProviderClass.getMethods()) {
if (!"getLastLocation".equals(method.getName())) {
continue;
}
Object object = locationServicesClass.getField("FusedLocationApi").get(null);
lastLocation = (Location) method.invoke(object, sGoogleApiClient);
break;
}
} catch (Exception e) {
// Location is not essential, so it's not an error
Log.v(LOG_TAG, "Exception on invoke onConnected for getLastLocation" + Log.getStackTraceString(e));
}
// Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(sGoogleApiClient);
if (lastLocation != null) {
sLocation = lastLocation.getLatitude() + "," + lastLocation.getLongitude();
Log.d(LOG_TAG, "Location received : " + sLocation);
} else {
sLocation = "";
}
newResourcesAvailable();
unregisterConnectionCallbacks();
}
// GoogleApiClient for Location failed somewhere
public void onConnectionSuspended() {
sLocation = "";
newResourcesAvailable();
unregisterConnectionCallbacks();
}
// GoogleApiClient for Location failed somewhere
public void onConnectionFailed() {
sLocation = "";
newResourcesAvailable();
unregisterConnectionCallbacks();
}
private void unregisterConnectionCallbacks(){
for (Method method : sGoogleApiClient.getClass().getMethods()) {
if (!"unregisterConnectionCallbacks".equals(method.getName())) {
continue;
}
try {
method.invoke(sGoogleApiClient, sGoogleApiClientListener);
} catch (Exception ignored) {
// Exception always occur here but cannot make it work
}
break;
}
for (Method method : sGoogleApiClient.getClass().getMethods()) {
if (!"unregisterConnectionFailedListener".equals(method.getName())) {
continue;
}
try {
method.invoke(sGoogleApiClient, sGoogleApiClientFailedListener);
} catch (Exception ignored) {
// Exception always occur here but cannot make it work
}
break;
}
}
protected class RetrieveAdvertisingId extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
String id = "";
try {
Object AdvertisingInfoObject = getAdvertisingInfoObject(mContext);
id = (String) invokeInstanceMethod(AdvertisingInfoObject, "getId", null);
} catch (Exception e) {
// Catch reflection exception and GooglePlayServicesNotAvailableException |
// GooglePlayServicesRepairableException
Log.e(LOG_TAG, "Exception while getting AdvertisingId", e);
}
return id;
}
#Override
protected void onPostExecute(String advertisingId) {
super.onPostExecute(advertisingId);
if (advertisingId != null && !advertisingId.isEmpty()) {
Log.i(LOG_TAG, "Advertising ID retrieved: " + advertisingId);
sAdvertisingId = advertisingId;
} else {
Log.e(LOG_TAG, "AdversitingId is not available");
sAdvertisingId = "";
}
AsynchronousParameterManager.this.newResourcesAvailable();
}
}
/**
* Returns the AdvertisingIdInfo object
*
* #param context the android context
* #return the advertising id information object
* #throws Exception
*/
private Object getAdvertisingInfoObject(Context context) throws Exception {
return invokeStaticMethod(
"com.google.android.gms.ads.identifier.AdvertisingIdClient",
"getAdvertisingIdInfo",
new Class[]{Context.class},
context
);
}
/**
* Invokes a static method within a class
* if it can be found on the classpath.
*
* #param className The full defined classname
* #param methodName The name of the method to invoke
* #param cArgs The args that the method can take
* #param args The args to pass to the method on invocation
* #return the result of the method invoke
* #throws Exception
*/
private Object invokeStaticMethod(String className, String methodName,
Class[] cArgs, Object... args) throws Exception {
Class classObject = Class.forName(className);
return invokeMethod(classObject, methodName, null, cArgs, args);
}
/**
* Invokes a method on a static instance
* within a class by reflection.
*
* #param instance The instance to invoke a method on
* #param methodName The name of the method to invoke
* #param cArgs The args that the method can take
* #param args The args to pass to the method on invocation
* #return the result of the method invoke
* #throws Exception
*/
private Object invokeInstanceMethod(Object instance, String methodName,
Class[] cArgs, Object... args) throws Exception {
Class classObject = instance.getClass();
return invokeMethod(classObject, methodName, instance, cArgs, args);
}
/**
* Invokes methods of a class via reflection
*
* #param classObject The class to attempt invocation on
* #param methodName The name of the method to invoke
* #param instance The object instance to invoke on
* #param cArgs The args that the method can take
* #param args The args to pass to the method on invocation
* #return the result of the method invoke
* #throws Exception
*/
private Object invokeMethod(Class classObject, String methodName, Object instance,
Class[] cArgs, Object... args) throws Exception {
Method methodObject = classObject.getMethod(methodName, cArgs);
return methodObject.invoke(instance, args);
}
private class GoogleApiClientListener implements InvocationHandler {
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
if (args != null) {
if (method.getName().equals("onConnected")) {
AsynchronousParameterManager.this.onConnected();
} else if (method.getName().equals("onConnectionSuspended") ) {
AsynchronousParameterManager.this.onConnectionSuspended();
}
} else {
return 0;
}
} catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
}
return null;
}
}
private class GoogleApiClientFailedListener implements InvocationHandler {
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
try {
if (method.getName().equals("onConnectionFailed")) {
AsynchronousParameterManager.this.onConnectionFailed();
}
return 0;
} catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
}
}
}
I have a .java file in which many methods like the following code exists, how can I refactor to make it cleaner?
public static void e(Throwable tr) {
if (!debug) {
return;
}
if (!allowE) return;
if (tr == null) {
return;
}
String content = wrapContent(tr.getMessage());
StackTraceElement caller = getCallerStackTraceElement();
String tag = generateTag(caller);
customLogger.e(tag, content, tr);
}
public static void i(String content) {
if (!debug) {
return;
}
if (!allowI) return;
content = wrapContent(content);
StackTraceElement caller = getCallerStackTraceElement();
String tag = generateTag(caller);
customLogger.i(tag, content);
}
========update======
This class is a wrapper of android.util.Log, for guys suggesting to follow naming conventions :).
You can strip most of the code into a shared method and then call that from both places.
public static voidcombined(String content, Throwable tr, bool allow)
{
if (!debug) return;
if (!allow) return;
content = wrapContent(content);
StackTraceElement caller = getCallerStackTraceElement();
String tag = generateTag(caller);
if (tr != null) {
customLogger.e(tag, content, tr);
} else {
customLogger.i(tag, content);
}
}
public static void e(Throwable tr) {
if (tr == null) {
return;
}
combined(tr.getMessage(), tr, allowE);
}
public static void i(String content) {
combined(content, null, allowI);
}
if (!debug) {
return;
}
if (!allowE) return;
appears twice, we can put it into a method isAllow()
String content = wrapContent(tr.getMessage());
StackTraceElement caller = getCallerStackTraceElement();
String tag = generateTag(caller);
appears twice too, and customLogger.e and customLogger.i is very alike. Lets put it into method logInLevel().
So, like this:
public static void e(Throwable tr) {
if (!isAllow()||tr==null) return ;
logInLevel(ERROR,tr.getMessage())
}
public static void i(String content) {
if (!isAllow()) return ;
logInLevel(INFO,content);
}
private static boolean isAllow(){
return debug&&allowE;
}
private static logInLevel(int level, String content){
StackTraceElement caller = getCallerStackTraceElement();
String tag = generateTag(caller);
if(level==INFO){
customLogger.i(tag, content);
}
else{//ERROR , you may add more log level here
customLogger.e(tag, content);
}
}
The idea is to apply the separation of concern design principle, to make sure that distinct section of your code are addressing specific concerns.
/**
* Logs error message
* #param tr a {#link Throwable} object containing the message to log
*/
public static void logErrorMessage(Throwable tr) {
if (tr == null) {
return;
}
logContent(tr.getMessage(), allowE, debug, LogLevel.ERROR);
}
/**
* Logs message
* #param content the message to log
* #param allow some variable
* #param debug check the debug status
* #param ll message log level
*/
public static void logContent(String content, boolean allow, boolean debug , LogLevel ll) {
if (!debug) || !allow) return;
switch(ll) {
case ERROR:
customLogger.e(getTag(content), content);
break;
case INFO:
customLogger.i(getTag(content), content);
break;
default:
}
}
/**
* Generates tag
* #param content the message to log
* #return a tagged string
*/
public static String getTag(String content) {
content = wrapContent(content);
return generateTag(getCallerStackTraceElement());
}
I'm having a problem with SAX XML parser.
It Does parse everything, except quotation marks (").
For example, if the text is hell"3o in a node, the result is hell.
Here are my codes:
XML Handler:
public class MyXMLHandler extends DefaultHandler {
Boolean currentElement = false;
String currentValue = null;
public static SitesList sitesList = null;
public static SitesList getSitesList() {
return sitesList;
}
public static void setSitesList(SitesList sitesList) {
MyXMLHandler.sitesList = sitesList;
}
/** Called when tag starts ( ex:- <name>AndroidPeople</name>
* -- <name> )*/
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currentElement = true;
if (localName.equals("channel"))
{
/** Start */
sitesList = new SitesList();
} else if (localName.equals("item")) {
String attr=attributes.getValue("item");
sitesList.setItem(attr);
} else if (localName.equals("title")) {
/** Get attribute value */
String attr = attributes.getValue("title");
sitesList.setTitle(attr);
}
else if (localName.equals("link")) {
/** Get attribute value */
String attr = attributes.getValue("link");
sitesList.setLink(attr);
}
else if (localName.equals("description")) {
/** Get attribute value */
String attr = attributes.getValue("description");
sitesList.setDescription(attr);
}
else if (localName.equalsIgnoreCase("pubDate")) {
/** Get attribute value */
String attr = attributes.getValue("pubDate");
sitesList.setPubDate(attr);
}
}
/** Called when tag closing ( ex:- <name>AndroidPeople</name>
* -- </name> )*/
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
currentElement = false;
/** set value */
if (localName.equalsIgnoreCase("item"))
sitesList.setItem(currentValue);
else if (localName.equalsIgnoreCase("title"))
sitesList.setTitle(currentValue);
else if (localName.equalsIgnoreCase("link"))
sitesList.setLink(currentValue);
else if (localName.equalsIgnoreCase("description"))
sitesList.setDescription(currentValue);
else if (localName.equalsIgnoreCase("pubDate"))
sitesList.setPubDate(currentValue);
}
/** Called to get tag characters ( ex:- <name>AndroidPeople</name>
* -- to get AndroidPeople Character ) */
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (currentElement) {
currentValue = new String(ch, start, length);
currentElement = false;
}
}
}
Getter and Setter:
import java.util.ArrayList;
/** Contains getter and setter method for variables */
public class SitesList {
/** Variables */
private ArrayList<String> title = new ArrayList<String>();
private ArrayList<String> link = new ArrayList<String>();
private ArrayList<String> description = new ArrayList<String>();
private ArrayList<String> pubDate = new ArrayList<String>();
private ArrayList<String> item=new ArrayList<String>();
/** In Setter method default it will return arraylist
* change that to add */
public ArrayList<String> getTitle() {
return title;
}
public void setTitle(String title) {
this.title.add(title);
}
public ArrayList<String> getLink() {
return link;
}
public void setLink(String link) {
this.link.add(link);
}
public ArrayList<String> getDescription() {
return description;
}
public void setDescription(String description) {
this.description.add(description);
}
public ArrayList<String> getPubDate() {
return this.pubDate;
}
public void setPubDate(String PubDate) {
this.pubDate.add(PubDate);
}
public ArrayList<String> getItem() {
return this.item;
}
public void setItem(String item) {
this.item.add(item);
}
}
And RSS Thread class:
public class RssThread {
private String title,html,pubDate;
public RssThread(String title,String html,String pubDate)
{
this.title=title;
this.html=html;
this.pubDate=CovertToDate(pubDate);
}
private String CovertToDate(String pubDate) {
// TODO Auto-generated method stub
//Wed, 28 Sep 2011 11:40:51//
String newDate="";
if (pubDate.substring(0,pubDate.indexOf(",")).equals("Sun"))
newDate+="יום ראשון";
else if (pubDate.subSequence(0, pubDate.indexOf(",")).equals("Mon"))
newDate+="יום שני";
else if (pubDate.subSequence(0, pubDate.indexOf(",")).equals("Tue"))
newDate+="יום שלישי";
else if (pubDate.subSequence(0, pubDate.indexOf(",")).equals("Wed"))
newDate+="יום רביעי";
else if (pubDate.subSequence(0, pubDate.indexOf(",")).equals("Thu"))
newDate+="יום חמישי";
else if (pubDate.subSequence(0, pubDate.indexOf(",")).equals("Fri"))
newDate+="יום שישי";
else if (pubDate.subSequence(0, pubDate.indexOf(",")).equals("Sat"))
newDate+="יום שבת";
newDate+=", ";
String[] splited = pubDate.split(" ");
newDate += splited[1]+".";
if (splited[2].equals("Jan"))
newDate+="1.";
else if (splited[2].equals("Feb"))
newDate+="2.";
else if (splited[2].equals("Mar"))
newDate+="3.";
else if (splited[2].equals("Apr"))
newDate+="4.";
else if (splited[2].equals("May"))
newDate+="5.";
else if (splited[2].equals("Jun"))
newDate+="6.";
else if (splited[2].equals("Jul"))
newDate+="7.";
else if (splited[2].equals("Aug"))
newDate+="8.";
else if (splited[2].equals("Sep"))
newDate+="9.";
else if (splited[2].equals("Oct"))
newDate+="10.";
else if (splited[2].equals("Nov"))
newDate+="11.";
else if (splited[2].equals("Dec"))
newDate+="12.";
newDate+=splited[3];
newDate+=", בשעה "+splited[4].substring(0,splited[4].lastIndexOf(":"));
return newDate;
}
public String getTitle() {
return this.title;
}
public String getHTML() {
return html;
}
public String getPubDate() {
return this.pubDate;
}
}
I have forgotten to put another class:
public class XMLParsingExample {
private static String[] RssString;
/** Create Object For SiteList Class */
SitesList sitesList = null;
/** Called when the activity is first created. */
/** Create a new textview array to display the results */
String[] title;
String[] link;
String[] pubDate;
{
try {
/** Handling XML */
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
/** Send URL to parse XML Tags */
URL sourceUrl = new URL(
"http://www.blich.co.il/rss.xml");
/** Create handler to handle XML Tags ( extends DefaultHandler ) */
MyXMLHandler myXMLHandler = new MyXMLHandler();
xr.setContentHandler(myXMLHandler);
xr.parse(new InputSource(sourceUrl.openStream()));
} catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
/** Get result from MyXMLHandler SitlesList Object */
sitesList = MyXMLHandler.sitesList;
/** Assign textview array lenght by arraylist size */
title = new String[sitesList.getTitle().size()];
link = new String[sitesList.getTitle().size()];
pubDate = new String[sitesList.getTitle().size()];
/** Set the result text in textview and add it to layout */
RssString=new String[sitesList.getItem().size()/2];
for (int i=0;i<RssString.length;i++)
RssString[i]="";
int counter=1;
for (int i = 0; i < sitesList.getItem().size(); i++) {
if (i%2!=0) {
title[i-counter]=sitesList.getTitle().get(i);
if (title[i-counter]!=null)
RssString[i-counter]+=title[i-counter]+"~";
link[i-counter]=sitesList.getLink().get(i);
if (link[i-counter]!=null)
RssString[i-counter]+=link[i-counter]+"~";
pubDate[i-counter]=sitesList.getPubDate().get(i);
if (pubDate[i-counter]!=null)
RssString[i-counter]+=pubDate[i-counter]+"~";
counter++;
}
}
}
public static String[] getRSSarray() {
return RssString;
}
}
I gave you all the codes so you can see everything.
the characters method can be called several times. try to look what you get in there and try to accumulate values in a stringbuffer
You can create an HTML object that will convert the HTML codes to the appropriate symbol (i.e. " to "), then convert that back to a String (or a SpannedString if you want to format it)
CharSequence seq = Html.fromHtml(title);
String str = new String(seq);
Maybe what both of you told me would work, but it would be complicated.
I have found an easier and more simple solution:
Other parser.
It uses 1 class (vs the sax parser that uses 3 classes), much much easier to understand, and of course, doesn't ignore quotation marks :D
Thanks anyway.
Have you tried to convert quotation marks to an XML entity, before you parse the element?
Several characters have special XML entity references:
& &
< <
> >
" "
' '
I would like to get the calling method java.lang.reflect.Method. NOT the name of the method.
Here is an example how to get the callers Class.
// find the callers class
Thread t = Thread.getCurrentThread();
Class<?> klass = Class.forName(t.getStackTrace()[2].getClassName());
// do something with the class (like processing its annotations)
...
It's for testing purpose only!
If it's just for testing, then this may work. It assumes that the class files are accessible via the calling class's ClassLoader and that the class files were compiled with debugging symbols (which I hope they are for testing!). This code relies on the ASM bytecode library.
public static Method getMethod(final StackTraceElement stackTraceElement) throws Exception {
final String stackTraceClassName = stackTraceElement.getClassName();
final String stackTraceMethodName = stackTraceElement.getMethodName();
final int stackTraceLineNumber = stackTraceElement.getLineNumber();
Class<?> stackTraceClass = Class.forName(stackTraceClassName);
// I am only using AtomicReference as a container to dump a String into, feel free to ignore it for now
final AtomicReference<String> methodDescriptorReference = new AtomicReference<String>();
String classFileResourceName = "/" + stackTraceClassName.replaceAll("\\.", "/") + ".class";
InputStream classFileStream = stackTraceClass.getResourceAsStream(classFileResourceName);
if (classFileStream == null) {
throw new RuntimeException("Could not acquire the class file containing for the calling class");
}
try {
ClassReader classReader = new ClassReader(classFileStream);
classReader.accept(
new EmptyVisitor() {
#Override
public MethodVisitor visitMethod(int access, final String name, final String desc, String signature, String[] exceptions) {
if (!name.equals(stackTraceMethodName)) {
return null;
}
return new EmptyVisitor() {
#Override
public void visitLineNumber(int line, Label start) {
if (line == stackTraceLineNumber) {
methodDescriptorReference.set(desc);
}
}
};
}
},
0
);
} finally {
classFileStream.close();
}
String methodDescriptor = methodDescriptorReference.get();
if (methodDescriptor == null) {
throw new RuntimeException("Could not find line " + stackTraceLineNumber);
}
for (Method method : stackTraceClass.getMethods()) {
if (stackTraceMethodName.equals(method.getName()) && methodDescriptor.equals(Type.getMethodDescriptor(method))) {
return method;
}
}
throw new RuntimeException("Could not find the calling method");
}
We can almost get there, here's a method that works in many cases. The problem is: it won't work reliably if there are overloaded methods (multiple methods with the same name). The stack trace does not provide the arguments, unfortunately.
private static Method getCallingMethod() throws ClassNotFoundException{
final Thread t = Thread.currentThread();
final StackTraceElement[] stackTrace = t.getStackTrace();
final StackTraceElement ste = stackTrace[2];
final String methodName = ste.getMethodName();
final String className = ste.getClassName();
Class<?> kls = Class.forName(className);
do{
for(final Method candidate : kls.getDeclaredMethods()){
if(candidate.getName().equals(methodName)){
return candidate;
}
}
kls = kls.getSuperclass();
} while(kls != null);
return null;
}
Test code:
public static void main(final String[] args) throws Exception{
System.out.println(getCallingMethod());
}
Output:
public static void foo.bar.Phleem.main(java.lang.String[]) throws java.lang.Exception
OK, here is a solution using ASM. It works for almost all cases:
private static Method getCallingMethod() throws ClassNotFoundException,
IOException{
final Thread t = Thread.currentThread();
final StackTraceElement[] stackTrace = t.getStackTrace();
final StackTraceElement ste = stackTrace[2];
final String methodName = ste.getMethodName();
final int lineNumber = ste.getLineNumber();
final String className = ste.getClassName();
final Class<?> kls = Class.forName(className);
final ClassReader cr = new ClassReader(className);
final EmptyVisitor empty = new EmptyVisitor();
final AtomicReference<Method> holder = new AtomicReference<Method>();
cr.accept(new ClassAdapter(empty){
#Override
public MethodVisitor visitMethod(
final int access,
final String name,
final String desc,
final String signature,
final String[] exceptions){
return name.equals(methodName) ? new MethodAdapter(empty){
#Override
public void visitLineNumber(final int line,
final Label start){
if(line >= lineNumber && holder.get() == null){
final Type[] argumentTypes =
Type.getArgumentTypes(desc);
final Class<?>[] argumentClasses =
new Class[argumentTypes.length];
try{
for(int i = 0; i < argumentTypes.length; i++){
final Type type = argumentTypes[i];
final String dd = type.getDescriptor();
argumentClasses[i] = getClassFromType(type);
}
holder.set(kls.getDeclaredMethod(methodName,
argumentClasses));
} catch(final ClassNotFoundException e){
throw new IllegalStateException(e);
} catch(final SecurityException e){
throw new IllegalStateException(e);
} catch(final NoSuchMethodException e){
throw new IllegalStateException(e);
}
}
super.visitLineNumber(line, start);
}
private Class<?> getClassFromType(final Type type) throws ClassNotFoundException{
Class<?> javaType;
final String descriptor = type.getDescriptor();
if(type.equals(Type.INT_TYPE)){
javaType = Integer.TYPE;
} else if(type.equals(Type.LONG_TYPE)){
javaType = Long.TYPE;
} else if(type.equals(Type.DOUBLE_TYPE)){
javaType = Double.TYPE;
} else if(type.equals(Type.FLOAT_TYPE)){
javaType = Float.TYPE;
} else if(type.equals(Type.BOOLEAN_TYPE)){
javaType = Boolean.TYPE;
} else if(type.equals(Type.BYTE_TYPE)){
javaType = Byte.TYPE;
} else if(type.equals(Type.CHAR_TYPE)){
javaType = Character.TYPE;
} else if(type.equals(Type.SHORT_TYPE)){
javaType = Short.TYPE;
} else if(descriptor.startsWith("[")){
final Class<?> elementType =
getClassFromType(type.getElementType());
javaType =
Array.newInstance(elementType, 0).getClass();
} else{
javaType = Class.forName(type.getClassName());
}
return javaType;
}
}
: null;
}
},
0);
return holder.get();
}
I'll leave it to you to refactor this into something readable. And it won't work if the signature of the calling method contains primitive arrays or multidimensional arrays. Obviously it only works if the class file contains line numbers.
Argghh, I work for ages and then I see that someone has come up with an almost identical solution!!! Anyway, I'll leave mine, because I developed it independently.
quite easy: just get the corresponding Class object first and then use Class.getMethod(String name,params...)
check here for the javadoc
public class GetMethod {
public static void main(String[] args){
new GetMethod().checkMethod();
}
public void checkMethod(){
Thread t=Thread.currentThread();
StackTraceElement element=t.getStackTrace()[1];
System.out.println(element.getClassName());
System.out.println(element.getMethodName());
try{
Method m=Class.forName(element.getClassName()).getMethod(element.getMethodName(),null);
System.out.println("Method: " + m.getName());
}catch (Exception e) {
e.printStackTrace();
}
}
}
hope that helped....
Here is a modified version of Sean Patrick Floyd's posted method for getting a Java Class from an ASM Type. It fixes a problem with multidimensional arrays and another problem with classes loaded by other classloaders.
public static Class<?> getClassFromType(Class<?> clazz, final Type type) throws ClassNotFoundException{
Class<?> javaType = null;
switch( type.getSort() ) {
case Type.VOID : javaType = Void.TYPE; break;
case Type.BOOLEAN : javaType = Boolean.TYPE; break;
case Type.CHAR : javaType = Character.TYPE; break;
case Type.BYTE : javaType = Byte.TYPE; break;
case Type.SHORT : javaType = Short.TYPE; break;
case Type.INT : javaType = Integer.TYPE; break;
case Type.FLOAT : javaType = Float.TYPE; break;
case Type.LONG : javaType = Long.TYPE; break;
case Type.DOUBLE : javaType = Double.TYPE; break;
case Type.ARRAY : javaType = Array.newInstance( getClassFromType( clazz, type.getElementType()), new int[type.getDimensions()] ).getClass(); break;
case Type.OBJECT : javaType = Class.forName( type.getClassName(), false, clazz.getClassLoader() ); break;
}
if ( javaType != null ) return javaType;
throw new ClassNotFoundException( "Couldn't find class for type " + type );
}