cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

How to create a Scheduler which can execute a custom class daily once in Windchill ?

vuchekar
9-Granite

How to create a Scheduler which can execute a custom class daily once in Windchill ?

Hi,

 

Right now we are fetching modified attribute values and we make a report daily once.

for now we are using CRON job script for executing the custom class on daily basis.

 

Is any way in Windchill to do same thing without using CRON job. 

Is any way in Windchill, so i can execute a program in Windchill on daily basis without user interpretation ?

 

Regards,

Vivek

 

 

 

12 REPLIES 12
Florent
14-Alexandrite
(To:vuchekar)

Hi Vivek,

 

you can create your own scheduled queue (wt.queue.ScheduleQueue).

sheduleQueue = QueueHelper.manager.createScheduleQueue(name).

sheduleQueue.addEntry(....)

 

Florent

Florent ROUSSEL
www.4cad.ca

Hello Florent,

 

Thanks for your response.

will you please explain this little more so i can pickup this fast.

 

Regards,

Vivek

Florent
14-Alexandrite
(To:vuchekar)

I recommend you to have a look on the customizer guide and the JavaDoc API.

 

Basically, you need to create a scheduleQueue using the method

public static ScheduleQueue newScheduleQueue(String name)

And add schedule task in this queue, using this method:

public ScheduleQueueEntry addEntry(WTPrincipal princ,
                                   String t_method,
                                   String t_class,
                                   Class[] arg_types,
                                   Object[] args,
                                   Timestamp sched_time)

 The method and class arguments specify the public static method you have implemented, arg_types and args are the arguments for the method, and finally the sched_time for the task itself.

 

You'll likely have to schedule the next task in your custom method.


Florent

Florent ROUSSEL
www.4cad.ca

Hi @Florent ,

Hope you're doing well! Its nice talking with you after a long time. 😊

I came across your reply to this. I am also working on similar kind of requirement, so I tried this approach; however, I am getting a NullPointerException. 

I tried debugging, but couldn't get any clue. Can you please suggest where I am going wrong? Here is my snippet.

 

public class AddQueueEntry {

	/**
	 * @param args
	 * @throws WTException
	 */
	@SuppressWarnings("rawtypes")
	public static void main(final String[] args) throws WTException {

		final String TRADE_AUTOMATION_SYNC_QUEUE = "SomeCustomScheduleQueueName";
		final String targetClass = AddQueueEntry.class.getName();
		final String targetMethod = "processEntries";
		final WTPrincipal principal = SessionHelper.getPrincipal();

		/* This is how to declare HashMap */
		final HashMap<String, String> keyValuePair = new HashMap<String, String>();

		/*Adding elements to HashMap*/
		keyValuePair.put("123456", "Value_1");
		keyValuePair.put("456789", "Value_2");
		keyValuePair.put("789123", "Value_3");
		keyValuePair.put("753951", "Value_4");

		final Class[] classArgs = new Class[1];
		classArgs[0] = HashMap.class;
		final Object[] objArgs = new Object[1];
		objArgs[0] = keyValuePair;

		final Calendar cal = Calendar.getInstance(SessionHelper.manager.getLocale());
		cal.add(Calendar.MINUTE, 1);
		final Timestamp startTime = new Timestamp(cal.getTimeInMillis());

		ScheduleQueue scheduleQueue = null;
		ScheduleQueueEntry scheduleQueueEntry = null;
		try {
			scheduleQueue = (ScheduleQueue) QueueHelper.manager.getQueue(TRADE_AUTOMATION_SYNC_QUEUE, ScheduleQueue.class);
			System.out.println("*** scheduleQueue >> " + scheduleQueue.getName());
			System.out.println("*** Session User >> " + principal);
			System.out.println("*** Target Class >> " + targetClass);
			System.out.println("*** Target Method >> " + targetMethod);
			System.out.println("*** classArgs >> " + classArgs[0]);
			System.out.println("*** objArgs >> " + objArgs[0]);
			System.out.println("*** startTime >> " + startTime);

			// Add an entry to queue
			scheduleQueueEntry = scheduleQueue.addEntry(principal, targetMethod, targetClass, classArgs, objArgs, startTime);
			System.out.println("*** Entry got added with number >> " + scheduleQueueEntry.getName());
		} catch (final WTException e1) {
			e1.printStackTrace();
		}
	}

	public static void processEntries(final HashMap<String, String> keyValuePair) {
		System.out.println("*** Total Objects Found :: " + keyValuePair.size());

		final Set<Entry<String, String>> set = keyValuePair.entrySet();
		final Iterator<Entry<String, String>> iterator = set.iterator();
		while(iterator.hasNext()) {
			final Entry<String, String> mentry = iterator.next();
			System.out.print("key is >> " + mentry.getKey() + " & Value is >> " + mentry.getValue());
		}
	}
}

 

 And here is error:

AddEntry.PNG

 

Thanks,

Shirish

 

Florent
14-Alexandrite
(To:ShirishMorkhade)

Hi Sirish,

 

the source code you shared is 63 lines while the error states a NPE at the line 69.

Without the good source, it's hard to debug.

 

 

Florent ROUSSEL
www.4cad.ca

Hi @Florent ,

Thanks for taking a look at this. I actually removed some lines before putting it here. 

Well, below is the line where I am getting NPE.

// Add an entry to queue
			scheduleQueueEntry = scheduleQueue.addEntry(principal, targetMethod, targetClass, classArgs, objArgs, startTime);

Thanks in advance!

Shirish

Florent
14-Alexandrite
(To:ShirishMorkhade)

Hi Sirish,

 

I don't see the issue. You might take a look at the MethodServer's log that should print the full stack trace.

 

Also, I'm not sure HashMap is a valid class for scheduled entry. It's usually ObjectReference.

 

Florent ROUSSEL
www.4cad.ca

What's the output in the method server log?

 

@ShirishMorkhade I got this working.

Per my earlier post I had been scheduling using batch file and Windows Task Scheduler.  That works fine but wanted to see if I could schedule in Windchill.

 

Initially I was getting the exact error you were getting, Null Pointer at 270 in ScheduleQueue.java.

I decompiled the class to see what what going on under the hood.  Everything looked fine.

BTW line 270 is 

I then wrote my own class based on the what I saw in ScheduleQueue.class.

 

I ran my class and the error said no active wt.method.MethodServerException: No active method context.

Once I saw that I knew I had the solution. I needed a RemoteMethodServer. Aha!

I re-ran my original code in a RemoteMethodSever and it workeds.

And yes, I an using the same addEntry() method you are using.

See image below.

I did create my own queue but that's probably not necessary.

 

Also, as @Florent mentioned to get it to reschedule just call the method doing the scheduling at the end of the method you specify in the addEntry() method.

In my test I just have the method append some text to a log file.  I reschedule to run in one minute.  It works!

d_graham_0-1632347930546.png

d_graham_1-1632349436974.png

 

Hope this helps,

 

David

Vivek,

 

We had the drive that stores the content files get fill up because the responsible party had never run “Remove Unreferenced File”. As a result the user’s could not upload files.

What I did to keep this from ever happening again is to write a batch file that runs the OOTB Remove Unreferenced Files Java tool and then using Windows Task scheduled the batch file to run once a month on the server where the vaults reside.

Works great.

 

Just thought I’d throw that out as another way to schedule any class to run on Windchill at regular intervals.

 

David

 

 

TomU
23-Emerald II
(To:d_graham)

@d_graham,

FWIW, cleanup of unreferenced files can automatically be scheduled now:

https://support.ptc.com/help/wnc/r12.0.1.0/en/index.html#page/Windchill_Help_Center/FileVaultConfigA...

 

Another helper was this script (linux) for moving the files out of the .unreferenced folders when you run that job.

 

#!/bin/bash -x
DATE=`date +%Y%m%d`
DIR_TARGET_BASE="/pdmlink/vaults/unreferenced/$DATE"
DIR_BASE="/pdmlink/vaults"

for folder in $(find $DIR_BASE -type d -maxdepth 1 \( ! -name .snapshot \)); do
DIR_SOURCE=${folder}/.unreferenced/
DIR_VAULT=${folder##*/}
DIR_TARGET="$DIR_TARGET_BASE/$DIR_VAULT/"
echo "Moving ${DIR_SOURCE} to ${DIR_TARGET} .."
mkdir -p "$DIR_TARGET"
mv $DIR_SOURCE $DIR_TARGET
done

 

This will move all the unreferenced files to a single folder by date where when you are ready, you can remove them. 

Announcements